From 99cabb4c1f005d38365ed54d9262c4bdc099e661 Mon Sep 17 00:00:00 2001 From: Stanca Pop Date: Mon, 26 Jun 2023 17:36:30 +0300 Subject: [PATCH 01/10] Delete CI/scripts --- CI/scripts/Docker | 10 - CI/scripts/Makefile | 124 ---- CI/scripts/Makefile2 | 128 ----- CI/scripts/adi_build.tcl | 78 --- CI/scripts/adi_env.tcl | 25 - CI/scripts/adi_ip.tcl | 660 ---------------------- CI/scripts/adi_ip_xilinx.tcl | 657 --------------------- CI/scripts/adi_project.tcl | 215 ------- CI/scripts/adi_project_xilinx.tcl | 435 -------------- CI/scripts/adi_xilinx_device_info_enc.tcl | 193 ------- CI/scripts/bsp.tmpl | 158 ------ CI/scripts/bsp_noexamples.tmpl | 162 ------ CI/scripts/build_bsp.m | 68 --- CI/scripts/build_bsp.sh | 273 --------- CI/scripts/copy_all_packed_ips.tcl | 74 --- CI/scripts/dockermake | 3 - CI/scripts/genTlbx.m | 96 ---- CI/scripts/genTlbx2.m | 101 ---- CI/scripts/linter.m | 23 - CI/scripts/pack_all_ips.tcl | 58 -- CI/scripts/ports.json | 178 ------ CI/scripts/read_ports_json.py | 59 -- CI/scripts/rename_common.py | 35 -- CI/scripts/setupDocker.sh | 8 - CI/scripts/synth_designs.sh | 22 - CI/scripts/targeting_designs.sh | 24 - 26 files changed, 3867 deletions(-) delete mode 100644 CI/scripts/Docker delete mode 100644 CI/scripts/Makefile delete mode 100644 CI/scripts/Makefile2 delete mode 100644 CI/scripts/adi_build.tcl delete mode 100644 CI/scripts/adi_env.tcl delete mode 100644 CI/scripts/adi_ip.tcl delete mode 100644 CI/scripts/adi_ip_xilinx.tcl delete mode 100644 CI/scripts/adi_project.tcl delete mode 100644 CI/scripts/adi_project_xilinx.tcl delete mode 100644 CI/scripts/adi_xilinx_device_info_enc.tcl delete mode 100644 CI/scripts/bsp.tmpl delete mode 100644 CI/scripts/bsp_noexamples.tmpl delete mode 100644 CI/scripts/build_bsp.m delete mode 100644 CI/scripts/build_bsp.sh delete mode 100644 CI/scripts/copy_all_packed_ips.tcl delete mode 100644 CI/scripts/dockermake delete mode 100644 CI/scripts/genTlbx.m delete mode 100644 CI/scripts/genTlbx2.m delete mode 100644 CI/scripts/linter.m delete mode 100644 CI/scripts/pack_all_ips.tcl delete mode 100644 CI/scripts/ports.json delete mode 100644 CI/scripts/read_ports_json.py delete mode 100644 CI/scripts/rename_common.py delete mode 100644 CI/scripts/setupDocker.sh delete mode 100644 CI/scripts/synth_designs.sh delete mode 100644 CI/scripts/targeting_designs.sh diff --git a/CI/scripts/Docker b/CI/scripts/Docker deleted file mode 100644 index 6c95c6f..0000000 --- a/CI/scripts/Docker +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:16.04 - -MAINTAINER Travis Collins -RUN DEBIAN_FRONTEND=noninteractive apt update -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libpng-dev libfreetype6-dev libblas-dev liblapack-dev gfortran build-essential xorg -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-8-jre openjdk-8-jdk libgtk2.0-0 libxss1 libxt6 zip unzip curl wget tar git xvfb -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y fakeroot libncurses5-dev libssl-dev ccache dfu-util u-boot-tools device-tree-compiler -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libssl-dev mtools bc python cpio zip unzip rsync file wget -RUN DEBIAN_FRONTEND=noninteractive dpkg --add-architecture i386 -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y lib32stdc++6 diff --git a/CI/scripts/Makefile b/CI/scripts/Makefile deleted file mode 100644 index 4e91c39..0000000 --- a/CI/scripts/Makefile +++ /dev/null @@ -1,124 +0,0 @@ -# Usage: -# make MLRELEASE= HDLBRANCH= -# Example -# make build MLRELEASE=R2018b HDLBRANCH=hdl_2018_r1 - -SHELL := /bin/bash - -MLFLAGS := -nodisplay -nodesktop -nosplash - -ifeq ($(MLRELEASE),) -MLRELEASE := R2021b -endif - -ifeq ($(HDLBRANCH),) -HDLBRANCH := hdl_2019_r1 -endif - -ifeq ($(OS),Windows_NT) -MLPATH := /cygdrive/c/Program\ Files/MATLAB -MLFLAGS := $(MLFLAGS) -wait -else -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Linux) -MLPATH := /usr/local/MATLAB -endif -ifeq ($(UNAME_S),Darwin) -MLPATH := /Applications -MLRELEASE := MATLAB_${MLRELEASE}.app -endif -endif - -ifeq ($(BOARD),) -BOARD := -endif - -ifeq ($(INCLUDE_EXAMPLES),) -INCLUDE_EXAMPLES := 1 -endif - -GITTAG := $(shell git describe --tags HEAD) - -.ONESHELL: -build: - # Uses the HDLBRANCH variable - bash build_bsp.sh - -add_libad9361: - cd ../.. ; \ - mkdir deps ; \ - cd deps ; \ - mkdir linux ; \ - cd linux ; \ - wget http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-trusty.tar.gz ; \ - tar xvf *.tar.gz ; \ - mv usr/local/lib/* . ; \ - mv usr/local/include ../ ; \ - rm -rf usr ; \ - rm *.tar.gz ; \ - cd .. ; \ - mkdir osx ; \ - cd osx ; \ - wget http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-osx_10.12.tar.gz ; \ - tar xvf *.tar.gz ; \ - cd ad9361* ; \ - mv usr/local/lib/ad9361.framework/Versions/Current/ad9361 ../libad9361.dylib ; \ - cd .. ; \ - rm -rf ad9361-*-Darwin ; \ - rm *.tar.gz ; \ - cd .. ; \ - mkdir win ; \ - cd win ; \ - wget "https://github.com/analogdevicesinc/libad9361-iio/releases/download/v0.2/libad9361-0.2-win64.zip" -O lib.zip ; \ - unzip lib.zip ; \ - mv libad9361-win64/* . ; \ - rm -rf libad9361-win64 ; \ - rm *.h ; \ - rm lib.zip - -test_installer: - cd ../.. ; \ - cp *.mltbx test/ ; \ - cp hdl/vendor/AnalogDevices/hdlcoder_board_customization.m test/hdlcoder_board_customization_local.m ; \ - sed -i "s/hdlcoder_board_customization/hdlcoder_board_customization_local/g" test/hdlcoder_board_customization_local.m ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('test');runInstallerTests('$(BOARD)');" - -test: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('test');runTests('$(BOARD)');" - -test_streaming: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "addpath(genpath('test'));addpath(genpath('deps'));runHWTests;" - -test_evm: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "addpath(genpath('test'));addpath(genpath('deps'));hwTestRunner;" - -test_modem: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "addpath(genpath('hdl'));cd('targeting');addpath(genpath('modem-qpsk'))" - -test_synth: - bash synth_designs.sh $(BOARD) - -test_targeting_demos: - bash targeting_designs.sh - -lte_pa_app: - cd ../../trx_examples/streaming/LTE_PA_App/ ; \ - bash genInstaller.sh $(MLPATH) $(MLRELEASE) $(MLFLAGS) - -gen_tlbx: - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "genTlbx($(INCLUDE_EXAMPLES));exit();" - -linter: - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "linter;exit();" - -doc: - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('../doc');genhtml();exit();" - -zip: - cd ../.. ; \ - mkdir zip ; \ - zip -r zip/AnalogDevicesBSP_$(GITTAG).zip deps doc hdl hil_models targeting info.xml LICENSE README.md test/*.log diff --git a/CI/scripts/Makefile2 b/CI/scripts/Makefile2 deleted file mode 100644 index cc2d2d9..0000000 --- a/CI/scripts/Makefile2 +++ /dev/null @@ -1,128 +0,0 @@ -# Usage: -# make MLRELEASE= HDLBRANCH= -# Example -# make build MLRELEASE=R2018b HDLBRANCH=hdl_2018_r1 - -SHELL := /bin/bash - -MLFLAGS := -nodisplay -nodesktop -nosplash - -ifeq ($(MLRELEASE),) -MLRELEASE := R2021a -endif - -ifeq ($(HDLBRANCH),) -HDLBRANCH := hdl_2019_r1 -endif - -ifeq ($(OS),Windows_NT) -MLPATH := /cygdrive/c/Program\ Files/MATLAB -MLFLAGS := $(MLFLAGS) -wait -else -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Linux) -MLPATH := /usr/local/MATLAB -endif -ifeq ($(UNAME_S),Darwin) -MLPATH := /Applications -MLRELEASE := MATLAB_${MLRELEASE}.app -endif -endif - -ifeq ($(BOARD),) -BOARD := -endif - -ifeq ($(INCLUDE_EXAMPLES),) -INCLUDE_EXAMPLES := 1 -endif - -GITTAG := $(shell git describe --tags HEAD) - -.ONESHELL: -build: - # Uses the HDLBRANCH variable - bash build_bsp.sh - -add_libad9361: - cd ../.. ; \ - mkdir deps ; \ - cd deps ; \ - mkdir linux ; \ - cd linux ; \ - wget http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-trusty.tar.gz ; \ - tar xvf *.tar.gz ; \ - mv usr/local/lib/* . ; \ - mv usr/local/include ../ ; \ - rm -rf usr ; \ - rm *.tar.gz ; \ - cd .. ; \ - mkdir osx ; \ - cd osx ; \ - wget http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-osx_10.12.tar.gz ; \ - tar xvf *.tar.gz ; \ - cd ad9361* ; \ - mv usr/local/lib/ad9361.framework/Versions/Current/ad9361 ../libad9361.dylib ; \ - cd .. ; \ - rm -rf ad9361-*-Darwin ; \ - rm *.tar.gz ; \ - cd .. ; \ - mkdir win ; \ - cd win ; \ - wget "https://github.com/analogdevicesinc/libad9361-iio/releases/download/v0.2/libad9361-0.2-win64.zip" -O lib.zip ; \ - unzip lib.zip ; \ - mv libad9361-win64/* . ; \ - rm -rf libad9361-win64 ; \ - rm *.h ; \ - rm lib.zip - -test_installer: - cd ../.. ; \ - cp *.mltbx test/ ; \ - cp hdl/vendor/AnalogDevices/hdlcoder_board_customization.m test/hdlcoder_board_customization_local.m ; \ - sed -i "s/hdlcoder_board_customization/hdlcoder_board_customization_local/g" test/hdlcoder_board_customization_local.m ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('test');runInstallerTests('$(BOARD)');" - -test: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('test');runTests('$(BOARD)');" - -test_ad4130: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('test');runAD4130Tests('$(BOARD)');" - -test_streaming: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "addpath(genpath('test'));addpath(genpath('deps'));runHWTests;" - -test_evm: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "addpath(genpath('test'));addpath(genpath('deps'));hwTestRunner;" - -test_modem: - cd ../.. ; \ - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "addpath(genpath('hdl'));cd('targeting');addpath(genpath('modem-qpsk'))" - -test_synth: - bash synth_designs.sh $(BOARD) - -test_targeting_demos: - bash targeting_designs.sh - -lte_pa_app: - cd ../../trx_examples/streaming/LTE_PA_App/ ; \ - bash genInstaller.sh $(MLPATH) $(MLRELEASE) $(MLFLAGS) - -gen_tlbx: - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "genTlbx($(INCLUDE_EXAMPLES));exit();" - -linter: - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "linter;exit();" - -doc: - ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('../doc');genhtml();exit();" - -zip: - cd ../.. ; \ - mkdir zip ; \ - zip -r zip/AnalogDevicesBSP_$(GITTAG).zip deps doc hdl hil_models targeting info.xml LICENSE README.md test/*.log \ No newline at end of file diff --git a/CI/scripts/adi_build.tcl b/CI/scripts/adi_build.tcl deleted file mode 100644 index f85bf7c..0000000 --- a/CI/scripts/adi_build.tcl +++ /dev/null @@ -1,78 +0,0 @@ -global fpga_board - -if {[info exists fpga_board]} { - puts "===========" - puts $fpga_board - puts "===========" -} else { - # Set to something not ZCU102 - set fpga_board "ZYNQ" -} - -# Build the project -update_compile_order -fileset sources_1 -reset_run impl_1 -reset_run synth_1 -launch_runs synth_1 -wait_on_run synth_1 -launch_runs impl_1 -to_step write_bitstream -wait_on_run impl_1 - -# Define local variables -set cdir [pwd] -set sdk_loc vivado_prj.sdk - -# Export the hdf -file delete -force $sdk_loc -file mkdir $sdk_loc -file copy -force vivado_prj.runs/impl_1/system_top.sysdef $sdk_loc/system_top.hdf - -# Close the Vivado project -close_project - -# Create the BOOT.bin -#exec xsdk -batch -source $cdir/projects/scripts/fsbl_build.tcl -tclargs $fpga_board -wait - -if {$fpga_board eq "ZCU102"} { - exec hsi -source $cdir/projects/scripts/pmufw_zynqmp.tcl - file copy -force $cdir/projects/scripts/fixmake.sh $cdir/fixmake.sh - exec chmod +x fixmake.sh - - #exec ./fixmake.sh - #cd pmufw - #exec make - #cd .. - if [catch "exec -ignorestderr ./fixmake.sh" ret opt] { - set makeRet [lindex [dict get $opt -errorcode] end] - puts "make returned with $makeRet" - } - if {[file exist pmufw/executable.elf] eq 0} { - puts "ERROR: pmufw not built" - return -code error 10 - } else { - puts "pmufw built correctly!" - } - - exec xsdk -batch -source $cdir/projects/scripts/fsbl_build_zynqmp.tcl - if {[file exist boot/BOOT.BIN] eq 0} { - puts "ERROR: BOOT.BIN not built" - return -code error 11 - } else { - puts "BOOT.BIN built correctly!" - } - -} else { - exec xsdk -batch -source $cdir/projects/scripts/fsbl_build_zynq.tcl - if {[file exist boot/BOOT.BIN] eq 0} { - puts "ERROR: BOOT.BIN not built" - return -code error 11 - } else { - puts "BOOT.BIN built correctly!" - } -} - -puts "------------------------------------" -puts "Embedded system build completed." -puts "You may close this shell." -puts "------------------------------------" -exit diff --git a/CI/scripts/adi_env.tcl b/CI/scripts/adi_env.tcl deleted file mode 100644 index 4e48bd9..0000000 --- a/CI/scripts/adi_env.tcl +++ /dev/null @@ -1,25 +0,0 @@ - -# environment related stuff - -set ad_hdl_dir [file normalize [file join [file dirname [info script]] "../.."]] - - -if [info exists ::env(ADI_HDL_DIR)] { - set ad_hdl_dir [file normalize $::env(ADI_HDL_DIR)] -} - - -# This helper pocedure retrieves the value of varible from environment if exists, -# other case returns the provided default value -# name - name of the environment variable -# default_value - returned vale in case environment variable does not exists -proc get_env_param {name default_value} { - if [info exists ::env($name)] { - puts "Getting from environment the parameter: $name=$::env($name) " - return $::env($name) - } else { - return $default_value - } -} - - diff --git a/CI/scripts/adi_ip.tcl b/CI/scripts/adi_ip.tcl deleted file mode 100644 index 301af4e..0000000 --- a/CI/scripts/adi_ip.tcl +++ /dev/null @@ -1,660 +0,0 @@ - -source hdl/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 cdir [pwd] - set m_file "" - set ip_constr_files_clean "" - foreach m_file $ip_constr_files { - file copy -force $m_file $cdir - set m_file [file tail $m_file] - lappend ip_constr_files_clean $m_file - } - set ip_constr_files $ip_constr_files_clean - - 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 -# -# 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 - 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 - } - } -} - -## 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 - } - } -} - -## List of all constraint files -# -set ip_constr_files "" - -## 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 ip_constr_files - global REQUIRED_VIVADO_VERSION - global IGNORE_VERSION_CHECK - - set VIVADO_VERSION [version -short] - 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" - } - - create_project $ip_name . -force - - ## Load custom message severity definitions - source $ad_hdl_dir/projects/scripts/adi_xilinx_msg.tcl - - set ip_constr_files "" - 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} { - - global ip_constr_files - - set cdir [pwd] - set ip_constr_files "" - set ip_files_clean "" - foreach m_file $ip_files { - file copy -force $m_file $cdir - set m_file [file tail $m_file] - puts $m_file - if {[file extension $m_file] eq ".xdc"} { - lappend ip_constr_files $m_file - } - lappend ip_files_clean $m_file - } - - set ip_files $ip_files_clean - - set proj_fileset [get_filesets sources_1] - add_files -norecurse -scan_for_includes -fileset $proj_fileset $ip_files - add_files -norecurse -copy_to $cdir -force -fileset $proj_fileset $ip_files - 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 ip_constr_files - - 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::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::save_core - - set i_filegroup [ipx::get_file_groups -of_objects [ipx::current_core] -filter {NAME =~ *synthesis*}] - foreach i_file $ip_constr_files { - set i_module [file tail $i_file] - regsub {_constr\.xdc} $i_module {} i_module - ipx::add_file $i_file $i_filegroup - ipx::reorder_files -front $i_file $i_filegroup - set_property SCOPED_TO_REF $i_module [ipx::get_files $i_file -of_objects $i_filegroup] - } - ipx::save_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" \ - "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] - } -} - diff --git a/CI/scripts/adi_ip_xilinx.tcl b/CI/scripts/adi_ip_xilinx.tcl deleted file mode 100644 index 45fdadb..0000000 --- a/CI/scripts/adi_ip_xilinx.tcl +++ /dev/null @@ -1,657 +0,0 @@ - -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 cdir [pwd] - set m_file "" - set ip_constr_files_clean "" - foreach m_file $ip_constr_files { - file copy -force $m_file $cdir - set m_file [file tail $m_file] - lappend ip_constr_files_clean $m_file - } - set ip_constr_files $ip_constr_files_clean - - 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 -# -# 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 - } - } -} - -## List of all constraint files -# -set ip_constr_files "" - -## 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 ip_constr_files - global REQUIRED_VIVADO_VERSION - global IGNORE_VERSION_CHECK - - set VIVADO_VERSION [version -short] - 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" - } - - create_project $ip_name . -force - - ## Load custom message severity definitions - source $ad_hdl_dir/projects/scripts/adi_xilinx_msg.tcl - - set ip_constr_files "" - set lib_dirs $ad_hdl_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} { - - global ip_constr_files - - set cdir [pwd] - set ip_constr_files "" - set ip_files_clean "" - foreach m_file $ip_files { - file copy -force $m_file $cdir - set m_file [file tail $m_file] - puts $m_file - if {[file extension $m_file] eq ".xdc"} { - lappend ip_constr_files $m_file - } - lappend ip_files_clean $m_file - } - - set ip_files $ip_files_clean - - set proj_fileset [get_filesets sources_1] - add_files -norecurse -scan_for_includes -fileset $proj_fileset $ip_files - add_files -norecurse -copy_to $cdir -force -fileset $proj_fileset $ip_files - 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 ip_constr_files - - 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] - } -} - diff --git a/CI/scripts/adi_project.tcl b/CI/scripts/adi_project.tcl deleted file mode 100644 index 2173764..0000000 --- a/CI/scripts/adi_project.tcl +++ /dev/null @@ -1,215 +0,0 @@ - -variable p_board -variable p_device -variable sys_zynq -variable p_prcfg_init -variable p_prcfg_list -variable p_prcfg_status - -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 -} - -set p_board "not-applicable" -set p_device "none" -set sys_zynq 1 -set ADI_POWER_OPTIMIZATION 0 - -proc adi_project_xilinx {project_name project_dir update_tcl {mode 0} {parameter_list ""}} { - - global ad_hdl_dir - global ad_phdl_dir - global p_board - global p_device - global sys_zynq - global REQUIRED_VIVADO_VERSION - global IGNORE_VERSION_CHECK - - if [regexp "_ac701$" $project_name] { - set p_device "xc7a200tfbg676-2" - set p_board "xilinx.com:ac701:part0:1.0" - set sys_zynq 0 - } - if [regexp "_kc705$" $project_name] { - set p_device "xc7k325tffg900-2" - set p_board "xilinx.com:kc705:part0:1.1" - set sys_zynq 0 - } - if [regexp "_vc707$" $project_name] { - set p_device "xc7vx485tffg1761-2" - set p_board "xilinx.com:vc707:part0:1.1" - set sys_zynq 0 - } - if [regexp "_kcu105$" $project_name] { - set p_device "xcku040-ffva1156-2-e" - set p_board "xilinx.com:kcu105:part0:1.1" - set sys_zynq 0 - } - if [regexp "_zed$" $project_name] { - set p_device "xc7z020clg484-1" - set p_board "em.avnet.com:zed:part0:1.3" - set sys_zynq 1 - } - if [regexp "_microzed$" $project_name] { - set p_device "xc7z010clg400-1" - set p_board "not-applicable" - set sys_zynq 1 - } - if [regexp "_zc702$" $project_name] { - set p_device "xc7z020clg484-1" - set p_board "xilinx.com:zc702:part0:1.2" - set sys_zynq 1 - } - if [regexp "_zc706$" $project_name] { - set p_device "xc7z045ffg900-2" - set p_board "xilinx.com:zc706:part0:1.2" - set sys_zynq 1 - } - if [regexp "_mitx045$" $project_name] { - set p_device "xc7z045ffg900-2" - set p_board "not-applicable" - set sys_zynq 1 - } - if [regexp "_zcu102$" $project_name] { - set p_device "xczu9eg-ffvb1156-2-e" - set p_board "xilinx.com:zcu102:part0:3.1" - set sys_zynq 2 - } - - #Added - set project_name_org $project_name - set project_name vivado_prj - - set VIVADO_VERSION [version -short] - 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" - } - - #Added - adi_setup_libs - - if {$mode == 0} { - set project_system_dir "./$project_name.srcs/sources_1/bd/system" - #Removed - #create_project $project_name . -part $p_device -force - } else { - set project_system_dir ".srcs/sources_1/bd/system" - #Removed - #create_project -in_memory -part $p_device - } - - if {$mode == 1} { - file mkdir $project_name.data - } - - if {$p_board ne "not-applicable"} { - set_property board_part $p_board [current_project] - } - - #Removed - #set lib_dirs $ad_hdl_dir/library - #if {$ad_hdl_dir ne $ad_phdl_dir} { - # lappend lib_dirs $ad_phdl_dir/library - #} - - #set_property ip_repo_paths $lib_dirs [current_fileset] - #update_ip_catalog - - set_msg_config -id {BD 41-1348} -new_severity info - set_msg_config -id {BD 41-1343} -new_severity info - set_msg_config -id {BD 41-1306} -new_severity info - set_msg_config -id {IP_Flow 19-1687} -new_severity info - set_msg_config -id {filemgmt 20-1763} -new_severity info - set_msg_config -severity {CRITICAL WARNING} -quiet -id {BD 41-1276} -new_severity error - - - #Added from adi_project_xilinx R2021a - # Set parameters of the top level file - # Make the same parameters available to system_bd.tcl - set proj_params [get_property generic [current_fileset]] - foreach {param value} $parameter_list { - lappend proj_params $param=$value - set ad_project_params($param) $value - } - - #Added - create_bd_design "system" - source $project_dir/system_bd.tcl - if {$project_name_org != "adrv9361z7035_ccbox_lvds_modem"} { - source $project_dir/$update_tcl - } - - set_property generic $proj_params [current_fileset] - regenerate_bd_layout - save_bd_design - validate_bd_design - - set_property synth_checkpoint_mode None [get_files $project_system_dir/system.bd] - generate_target {synthesis implementation} [get_files $project_system_dir/system.bd] - make_wrapper -files [get_files $project_system_dir/system.bd] -top - - if {$mode == 0} { - import_files -force -norecurse -fileset sources_1 $project_system_dir/hdl/system_wrapper.v - } else { - write_hwdef -file "$project_name.data/$project_name.hwdef" - } -} - -#Added -proc adi_setup_libs {} { - global ad_hdl_dir - global ad_phdl_dir - - set lib_dirs [get_property ip_repo_paths [current_fileset]] - - lappend lib_dirs $ad_hdl_dir/library - if {$ad_hdl_dir ne $ad_phdl_dir} { - lappend lib_dirs $ad_phdl_dir/library - } - - set_property ip_repo_paths $lib_dirs [current_fileset] - update_ip_catalog - adi_add_archive_ip $lib_dirs -} - -#Added -proc adi_add_archive_ip {lib_dirs} { - global ad_hdl_dir - global ad_phdl_dir - foreach libDir $lib_dirs { - set ipList [glob -nocomplain -directory $libDir *.zip] - foreach ipCore $ipList { - catch {update_ip_catalog -add_ip $ipCore -repo_path $libDir} - file delete -force $ipCore - } - } -} - -proc adi_project_files {project_name project_files} { - - global ad_hdl_dir - global ad_phdl_dir - global proj_dir - - #Added - cd $proj_dir - - add_files -norecurse -fileset sources_1 $project_files - set_property top system_top [current_fileset] - - #Added - cd $ad_hdl_dir -} - -proc adi_project_run {project_name} { - #Removed -} - diff --git a/CI/scripts/adi_project_xilinx.tcl b/CI/scripts/adi_project_xilinx.tcl deleted file mode 100644 index 6f49244..0000000 --- a/CI/scripts/adi_project_xilinx.tcl +++ /dev/null @@ -1,435 +0,0 @@ - -## Define the supported tool version -if {![info exists REQUIRED_VIVADO_VERSION]} { - set REQUIRED_VIVADO_VERSION "2019.1" -} - -## Define the ADI_IGNORE_VERSION_CHECK environment variable to skip version check -if {[info exists ::env(ADI_IGNORE_VERSION_CHECK)]} { - set IGNORE_VERSION_CHECK 1 -} elseif {![info exists IGNORE_VERSION_CHECK]} { - set IGNORE_VERSION_CHECK 0 -} - -## Define the ADI_USE_OOC_SYNTHESIS environment variable to enable out of context -# synthesis -if {[info exists ::env(ADI_USE_OOC_SYNTHESIS)]} { - set ADI_USE_OOC_SYNTHESIS 1 -} elseif {![info exists ADI_USE_OOC_SYNTHESIS]} { - set ADI_USE_OOC_SYNTHESIS 0 -} - -## Set to enable incremental compilation -set ADI_USE_INCR_COMP 1 - -## Set to enable power optimization -set ADI_POWER_OPTIMIZATION 0 - -## Initialize global variables -set p_board "not-applicable" -set p_device "none" -set sys_zynq 1 - -set p_prcfg_init "" -set p_prcfg_list "" -set p_prcfg_status "" - -## Creates a Xilinx project. -# -# \param[project_name] - name of the project -# \param[mode] - if set non-project mode will be used, otherwise project mode -# flow, see UG892 for more information -# \param[parameter_list] - a list of global parameters (parameters of the -# system_top module) -# -# Supported carrier names are: ac701, kc705, vc707, vcu118, kcu105, zed, -# microzed, zc702, zc706, mitx405, zcu102. -# -proc adi_project {project_name {mode 0} {parameter_list {}} } { - - global ad_hdl_dir - global p_board - global p_device - global sys_zynq - global REQUIRED_VIVADO_VERSION - global IGNORE_VERSION_CHECK - global ADI_USE_OOC_SYNTHESIS - global ADI_USE_INCR_COMP - - if [regexp "_ac701$" $project_name] { - set p_device "xc7a200tfbg676-2" - set p_board "xilinx.com:ac701:part0:1.0" - set sys_zynq 0 - } - if [regexp "_kc705$" $project_name] { - set p_device "xc7k325tffg900-2" - set p_board "xilinx.com:kc705:part0:1.1" - set sys_zynq 0 - } - if [regexp "_vc707$" $project_name] { - set p_device "xc7vx485tffg1761-2" - set p_board "xilinx.com:vc707:part0:1.1" - set sys_zynq 0 - } - if [regexp "_vcu118$" $project_name] { - set p_device "xcvu9p-flga2104-2L-e" - set p_board "xilinx.com:vcu118:part0:2.0" - set sys_zynq 0 - } - if [regexp "_kcu105$" $project_name] { - set p_device "xcku040-ffva1156-2-e" - set p_board "xilinx.com:kcu105:part0:1.1" - set sys_zynq 0 - } - if [regexp "_zed$" $project_name] { - set p_device "xc7z020clg484-1" - set p_board "em.avnet.com:zed:part0:1.3" - set sys_zynq 1 - } - if [regexp "_coraz7s$" $project_name] { - set p_device "xc7z007sclg400-1" - set p_board "not-applicable" - set sys_zynq 1 - } - if [regexp "_microzed$" $project_name] { - set p_device "xc7z010clg400-1" - set p_board "not-applicable" - set sys_zynq 1 - } - if [regexp "_zc702$" $project_name] { - set p_device "xc7z020clg484-1" - set p_board "xilinx.com:zc702:part0:1.2" - set sys_zynq 1 - } - if [regexp "_zc706$" $project_name] { - set p_device "xc7z045ffg900-2" - set p_board "xilinx.com:zc706:part0:1.2" - set sys_zynq 1 - } - if [regexp "_mitx045$" $project_name] { - set p_device "xc7z045ffg900-2" - set p_board "not-applicable" - set sys_zynq 1 - } - if [regexp "_zcu102$" $project_name] { - set p_device "xczu9eg-ffvb1156-2-e" - set p_board "xilinx.com:zcu102:part0:3.2" - set sys_zynq 2 - } - - set VIVADO_VERSION [version -short] - 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" - } - - if {$mode == 0} { - set project_system_dir "./$project_name.srcs/sources_1/bd/system" - create_project $project_name . -part $p_device -force - } else { - set project_system_dir ".srcs/sources_1/bd/system" - create_project -in_memory -part $p_device - } - - if {$mode == 1} { - file mkdir $project_name.data - } - - if {$p_board ne "not-applicable"} { - set_property board_part $p_board [current_project] - } - - set lib_dirs $ad_hdl_dir/library - - # Set a common IP cache for all projects - if {$ADI_USE_OOC_SYNTHESIS == 1} { - if {[file exists $ad_hdl_dir/ipcache] == 0} { - file mkdir $ad_hdl_dir/ipcache - } - config_ip_cache -import_from_project -use_cache_location $ad_hdl_dir/ipcache - } - - set_property ip_repo_paths $lib_dirs [current_fileset] - update_ip_catalog - - ## Load custom message severity definitions - source $ad_hdl_dir/projects/scripts/adi_xilinx_msg.tcl - - ## In Vivado there is a limit for the number of warnings and errors which are - ## displayed by the tool for a particular error or warning; the default value - ## of this limit is 100. - ## Overrides the default limit to 2000. - set_param messaging.defaultLimit 2000 - - # Set parameters of the top level file - # Make the same parameters available to system_bd.tcl - set proj_params [get_property generic [current_fileset]] - foreach {param value} $parameter_list { - lappend proj_params $param=$value - set ad_project_params($param) $value - } - set_property generic $proj_params [current_fileset] - - create_bd_design "system" - source system_bd.tcl - - save_bd_design - validate_bd_design - - if {$ADI_USE_OOC_SYNTHESIS == 1} { - set_property synth_checkpoint_mode Hierarchical [get_files $project_system_dir/system.bd] - } else { - set_property synth_checkpoint_mode None [get_files $project_system_dir/system.bd] - } - generate_target {synthesis implementation} [get_files $project_system_dir/system.bd] - if {$ADI_USE_OOC_SYNTHESIS == 1} { - export_ip_user_files -of_objects [get_files $project_system_dir/system.bd] -no_script -sync -force -quiet - create_ip_run [get_files $project_system_dir/system.bd] - } - make_wrapper -files [get_files $project_system_dir/system.bd] -top - - if {$mode == 0} { - import_files -force -norecurse -fileset sources_1 $project_system_dir/hdl/system_wrapper.v - } else { - write_hwdef -file "$project_name.data/$project_name.hwdef" - } - - if {$ADI_USE_INCR_COMP == 1} { - if {[file exists ./reference.dcp]} { - set_property incremental_checkpoint ./reference.dcp [get_runs impl_1] - } - } - -} - -## Add source files to an exiting project. -# -# \param[project_name] - name of the project -# \param[project_files] - list of project files -# -proc adi_project_files {project_name project_files} { - - foreach pfile $project_files { - if {[string range $pfile [expr 1 + [string last . $pfile]] end] == "xdc"} { - add_files -norecurse -fileset constrs_1 $pfile - } else { - add_files -norecurse -fileset sources_1 $pfile - } - } - - # NOTE: top file name is always system_top - set_property top system_top [current_fileset] -} - -## Run an existing project (generate bit stream). -# -# \param[project_name] - name of the project -# -proc adi_project_run {project_name} { - - global ADI_POWER_OPTIMIZATION - global ADI_USE_OOC_SYNTHESIS - - if {$ADI_USE_OOC_SYNTHESIS == 1} { - launch_runs -jobs 4 system_*_synth_1 synth_1 - } else { - launch_runs synth_1 - } - wait_on_run synth_1 - open_run synth_1 - report_timing_summary -file timing_synth.log - - if {![info exists ::env(ADI_NO_BITSTREAM_COMPRESSION)] && ![info exists ADI_NO_BITSTREAM_COMPRESSION]} { - set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] - } - - if {$ADI_POWER_OPTIMIZATION == 1} { - set_property STEPS.POWER_OPT_DESIGN.IS_ENABLED true [get_runs impl_1] - set_property STEPS.POST_PLACE_POWER_OPT_DESIGN.IS_ENABLED true [get_runs impl_1] - } - - launch_runs impl_1 -to_step write_bitstream - wait_on_run impl_1 - open_run impl_1 - report_timing_summary -file timing_impl.log - - if {[info exists ::env(ADI_GENERATE_UTILIZATION)]} { - set csv_file resource_utilization.csv - if {[ catch { - xilinx::designutils::report_failfast -csv -file $csv_file -transpose -no_header -ignore_pr -quiet - set MMCM [llength [get_cells -hierarchical -filter { PRIMITIVE_TYPE =~ *MMCM* }]] - set PLL [llength [get_cells -hierarchical -filter { PRIMITIVE_TYPE =~ *PLL* }]] - set worst_slack_setup [get_property SLACK [get_timing_paths -setup]] - set worst_slack_hold [get_property SLACK [get_timing_paths -hold]] - - set fileRead [open $csv_file r] - set lines [split [read $fileRead] "\n"] - set names_line [lindex $lines end-3] - set values_line [lindex $lines end-2] - close $fileRead - - set fileWrite [open $csv_file w] - puts $fileWrite "$names_line,MMCM*,PLL*,Worst_Setup_Slack,Worst_Hold_Slack" - puts $fileWrite "$values_line,$MMCM,$PLL,$worst_slack_setup,$worst_slack_hold" - close $fileWrite - } issue ] != 0 } { - puts "GENERATE_REPORTS: tclapp::xilinx::designutils not installed" - } - } else { - puts "GENERATE_REPORTS: Resource utilization files won't be generated because ADI_GENERATE_UTILIZATION env var is not set" - } - - # Look for undefined clocks which do not show up in the timing summary - set timing_check [check_timing -override_defaults no_clock -no_header -return_string] - if {[regexp { (\d+) register} $timing_check -> num_regs]} { - - if {[info exist num_regs]} { - if {$num_regs > 0} { - puts "CRITICAL WARNING: There are $num_regs registers with no clocks !!! See no_clock.log for details." - check_timing -override_defaults no_clock -verbose -file no_clock.log - } - } - - } else { - puts "CRITICAL WARNING: The search for undefined clocks failed !!!" - } - - file mkdir $project_name.sdk - - if [expr [string match *VIOLATED* $[report_timing_summary -return_string]] == 1] { - file copy -force $project_name.runs/impl_1/system_top.sysdef $project_name.sdk/system_top_bad_timing.hdf - return -code error [format "ERROR: Timing Constraints NOT met!"] - } else { - file copy -force $project_name.runs/impl_1/system_top.sysdef $project_name.sdk/system_top.hdf - } -} - -## Run synthesis on an partial design; use it in Partial Reconfiguration flow. -# -# \param[project_name] - project name -# \param[prcfg_name] - name of the partial design -# \param[hdl_files] - hdl source of the partial design -# \param[xdc_files] - XDC constraint source of the partial design -# -proc adi_project_synth {project_name prcfg_name hdl_files {xdc_files ""}} { - - global p_device - - set p_prefix "$project_name.data/$project_name" - - if {$prcfg_name eq ""} { - - read_verilog .srcs/sources_1/bd/system/hdl/system_wrapper.v - read_verilog $hdl_files - read_xdc $xdc_files - - synth_design -mode default -top system_top -part $p_device > $p_prefix.synth.rds - write_checkpoint -force $p_prefix.synth.dcp - close_project - - } else { - - create_project -in_memory -part $p_device - read_verilog $hdl_files - synth_design -mode out_of_context -top "prcfg" -part $p_device > $p_prefix.${prcfg_name}_synth.rds - write_checkpoint -force $p_prefix.${prcfg_name}_synth.dcp - close_project - } -} - -## Run implementation on an partial design; use it in Partial Reconfiguration -# flow. -# -# \param[project_name] - project name -# \param[prcfg_name] - name of the partial design -# \param[xdc_files] - XDC constraint source of the partial design -# -proc adi_project_impl {project_name prcfg_name {xdc_files ""}} { - - global p_device - global p_prcfg_init - global p_prcfg_list - global p_prcfg_status - - set p_prefix "$project_name.data/$project_name" - - if {$prcfg_name eq "default"} { - set p_prcfg_status 0 - set p_prcfg_list "" - set p_prcfg_init "$p_prefix.${prcfg_name}_impl.dcp" - file mkdir $project_name.sdk - } - - if {$prcfg_name eq "default"} { - - open_checkpoint $p_prefix.synth.dcp -part $p_device - read_xdc $xdc_files - read_checkpoint -cell i_prcfg $p_prefix.${prcfg_name}_synth.dcp - set_property HD.RECONFIGURABLE 1 [get_cells i_prcfg] - opt_design > $p_prefix.${prcfg_name}_opt.rds - write_debug_probes -force $p_prefix.${prcfg_name}_debug_nets.ltx - place_design > $p_prefix.${prcfg_name}_place.rds - route_design > $p_prefix.${prcfg_name}_route.rds - - } else { - - open_checkpoint $p_prefix.default_impl_bb.dcp -part $p_device - lock_design -level routing - read_checkpoint -cell i_prcfg $p_prefix.${prcfg_name}_synth.dcp - read_xdc $xdc_files - opt_design > $p_prefix.${prcfg_name}_opt.rds - place_design > $p_prefix.${prcfg_name}_place.rds - route_design > $p_prefix.${prcfg_name}_route.rds - } - - write_checkpoint -force $p_prefix.${prcfg_name}_impl.dcp - report_utilization -pblocks pb_prcfg -file $p_prefix.${prcfg_name}_utilization.rpt - report_timing_summary -file $p_prefix.${prcfg_name}_timing_summary.rpt - - if [expr [get_property SLACK [get_timing_paths]] < 0] { - set p_prcfg_status 1 - puts "CRITICAL WARNING: Timing Constraints NOT met ($prcfg_name)!" - } - - write_checkpoint -force -cell i_prcfg $p_prefix.${prcfg_name}_prcfg_impl.dcp - update_design -cell i_prcfg -black_box - write_checkpoint -force $p_prefix.${prcfg_name}_impl_bb.dcp - open_checkpoint $p_prefix.${prcfg_name}_impl.dcp -part $p_device - write_bitstream -force -bin_file -file $p_prefix.${prcfg_name}.bit - write_sysdef -hwdef $p_prefix.hwdef -bitfile $p_prefix.${prcfg_name}.bit -file $p_prefix.${prcfg_name}.hdf - file copy -force $p_prefix.${prcfg_name}.hdf $project_name.sdk/system_top.${prcfg_name}.hdf - - if {$prcfg_name ne "default"} { - lappend p_prcfg_list "$p_prefix.${prcfg_name}_impl.dcp" - } - - if {$prcfg_name eq "default"} { - file copy -force $p_prefix.${prcfg_name}.hdf $project_name.sdk/system_top.hdf - } -} - -## Verify an implemented partial reconfiguration design, checks if all the -# partial design are compatible with the base design. -# -# \param[project_name] - project name -# -proc adi_project_verify {project_name} { - - # checkpoint for the default design - global p_prcfg_init - # list of checkpoints with all the PRs integrated into the default design - global p_prcfg_list - global p_prcfg_status - - set p_prefix "$project_name.data/$project_name" - - pr_verify -full_check -initial $p_prcfg_init \ - -additional $p_prcfg_list \ - -file $p_prefix.prcfg_verify.log - - if {$p_prcfg_status == 1} { - return -code error [format "ERROR: Timing Constraints NOT met!"] - } -} - diff --git a/CI/scripts/adi_xilinx_device_info_enc.tcl b/CI/scripts/adi_xilinx_device_info_enc.tcl deleted file mode 100644 index af8b840..0000000 --- a/CI/scripts/adi_xilinx_device_info_enc.tcl +++ /dev/null @@ -1,193 +0,0 @@ -## *************************************************************************** -## *************************************************************************** -## 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: -## -## -## 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 }} - -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)!" - } - } -} - - -## *************************************************************************** -## *************************************************************************** diff --git a/CI/scripts/bsp.tmpl b/CI/scripts/bsp.tmpl deleted file mode 100644 index 6dac3cf..0000000 --- a/CI/scripts/bsp.tmpl +++ /dev/null @@ -1,158 +0,0 @@ - - - Analog Devices, Inc. Precision Toolbox - Analog Devices, Inc - - Analog Devices, Inc - Board support package for control and data streaming from Analog Devices Precision products. - Scripts and tools created by ADI to be used with MATLAB and Simulink with ADI Precision products -Documentation: https://wiki.analog.com/resources/tools-software/pcx-toolbox -Support: https://ez.analog.com/ - __REPO-ROOT__/CI/doc/ADI_Logo_AWP_Large.png - __VERSION__ - ${PROJECT_ROOT}/Analog Devices Board Support Packages.mltbx - - MATLAB - Simulink - Communications Toolbox - DSP System Toolbox - Signal Processing Toolbox - - - 1 - 2 - 36 - 24 - 101 - 8 - 14 - - - 9.5 - 9.2 - 7.0 - 9.7 - 3.13 - 8.1 - 9.0 - - - __UUID__ - % -CI/* -hdl_prj/* -slprj/* -.git/* -test/* -itests/* -mltbx/* -*~ -.Xil/* - true - - - - - ${PROJECT_ROOT}/info.xml - - - - false - __ML-RELEASE__ - __ML-RELEASE__ - true - true - false - true - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - __REPO-ROOT__ - - - ${PROJECT_ROOT}/LICENSE - ${PROJECT_ROOT}/README.md - ${PROJECT_ROOT}/doc - ${PROJECT_ROOT}/info.xml - ${PROJECT_ROOT}/rfm_examples - - - - - - - __REPO-ROOT__/AnalogDevicesPrecision.mltbx - - - - /usr/local/MATLAB/__ML-RELEASE__ - - - - - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - false - false - false - false - false - true - false - 4.15.0-34-generic - false - true - glnxa64 - true - - - diff --git a/CI/scripts/bsp_noexamples.tmpl b/CI/scripts/bsp_noexamples.tmpl deleted file mode 100644 index 15aac74..0000000 --- a/CI/scripts/bsp_noexamples.tmpl +++ /dev/null @@ -1,162 +0,0 @@ - - - Analog Devices, Inc. Transceiver Toolbox - Travis Collins - travis.collins@analog.com - Analog Devices, Inc - Board support package for HDL targeting and data streaming from Analog Devices transceivers. - Scripts and tools created by ADI to be used with MATLAB and Simulink with ADI transceivers -Documentation: https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/software/matlab_bsp -Support: https://ez.analog.com/ - __REPO-ROOT__/CI/doc/ADI_Logo_AWP_Large.png - __VERSION__ - ${PROJECT_ROOT}/AnalogDevicesTransceiverToolbox.mltbx - - MATLAB - Simulink - Communications Toolbox - DSP System Toolbox - HDL Coder - Signal Processing Toolbox - Simulink Coder - - - 1 - 2 - 36 - 24 - 101 - 8 - 14 - - - 9.5 - 9.2 - 7.0 - 9.7 - 3.13 - 8.1 - 9.0 - - - __UUID__ - % -CI/* -deps/* -hdl_prj/* -slprj/* -.git/* -test/* -itests/* -mltbx/* -trx_examples/* -*~ -.Xil/* - true - - - - - ${PROJECT_ROOT}/info.xml - - - - false - __ML-RELEASE__ - __ML-RELEASE__ - true - true - false - true - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - __REPO-ROOT__ - - - ${PROJECT_ROOT}/LICENSE - ${PROJECT_ROOT}/README.md - ${PROJECT_ROOT}/doc - ${PROJECT_ROOT}/hdl - ${PROJECT_ROOT}/info.xml - - - - - - - __REPO-ROOT__/AnalogDevicesTransceiverToolbox.mltbx - - - - /usr/local/MATLAB/__ML-RELEASE__ - - - - - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - false - false - false - false - false - true - false - 4.15.0-34-generic - false - true - glnxa64 - true - - - diff --git a/CI/scripts/build_bsp.m b/CI/scripts/build_bsp.m deleted file mode 100644 index 6acdc33..0000000 --- a/CI/scripts/build_bsp.m +++ /dev/null @@ -1,68 +0,0 @@ -%% Move to correct location -p = mfilename('fullpath'); -p = strsplit(p,'/'); -p = p(1:end-1); -p = strjoin(p,'/'); -cd(p); -cd .. - -%% Setup HDL repo -system('git clone --single-branch -b hdl_2018_r1 https://github.com/analogdevicesinc/hdl.git') -system('source /opt/Xilinx/Vivado/2017.4/settings64.sh'); - -%% Update adi_ip script to make sure archive are built in a portable way -copyfile('scripts/adi_ip.tcl', 'hdl/library/scripts/') - -%% Pack all cores -system('/opt/Xilinx/Vivado/2017.4/bin/vivado -mode batch -source scripts/pack_all_ips.tcl && echo "success" || echo "failed"') - -%% Repack i2s core to include xml files -cd hdl/library/axi_i2s_adi/ -unzip('analog.com_user_axi_i2s_adi_1.0.zip','tmp') -delete('analog.com_user_axi_i2s_adi_1.0.zip') -copyfile('*.xml','tmp') -zip('analog.com_user_axi_i2s_adi_1.0.zip',{'*'},'tmp'); -cd ../../.. - -cd hdl/library/util_i2c_mixer/ -unzip('analog.com_user_util_i2c_mixer_1.0.zip','tmp') -delete('analog.com_user_util_i2c_mixer_1.0.zip') -copyfile('*.xml','tmp') -zip('analog.com_user_util_i2c_mixer_1.0.zip',{'*'},'tmp'); -cd ../../.. - -%% Move all cores -system('/opt/Xilinx/Vivado/2017.4/bin/vivado -mode batch -source scripts/copy_all_packed_ips.tcl && echo "success" || echo "failed"') -!cp -r hdl/library/jesd204/*.zip hdl/library/ -!cp -r hdl/library/xilinx/*.zip hdl/library/ -!rm -rf hdl/projects -!cp -r projects hdl/ - -%% Remove unused projects in BSP -% cd hdl/projects -% whitelist = {'..','.','scripts','fmcomms5','fmcomms2','common','adrv9361z7035','adrv9364z7020','adrv9009'}; -% files = dir('.'); -% files = {files.name}; -% for file = files -% if ~ismember(file{:},whitelist) -% disp(file{:}) -% if isfile(file{:}) -% delete(file{:}); -% elseif isfolder(file{:}) -% rmdir(file{:},'s'); -% end -% end -% end -% cd ../.. - -%% Update tcl scripts and additional IP cores (MUX) -copyfile('scripts/adi_project.tcl', 'hdl/projects/scripts/') -copyfile('scripts/adi_build.tcl', 'hdl/projects/scripts/') -copyfile('ip/*.zip', 'hdl/library/') -movefile('hdl','../../hdl_wa_bsp/vendor/AnalogDevices/vivado') - -%% Cleanup -delete('vivado_*') -delete('vivado.jou') -delete('vivado.log') - diff --git a/CI/scripts/build_bsp.sh b/CI/scripts/build_bsp.sh deleted file mode 100644 index 5a7d1a8..0000000 --- a/CI/scripts/build_bsp.sh +++ /dev/null @@ -1,273 +0,0 @@ -#!/bin/bash -set -x - -if [ -z "${HDLBRANCH}" ]; then -HDLBRANCH='hdl_2019_r2' -fi - - -# Script is designed to run from specific location -scriptdir=`dirname "$BASH_SOURCE"` -cd $scriptdir -cd .. - -# Get HDL -if [ -d "hdl" ]; then - rm -rf "hdl" -fi -for i in {1..5} -do - if git clone --single-branch -b $HDLBRANCH https://github.com/analogdevicesinc/hdl.git - then - break - fi - if [ -d "hdl" ]; then - break - fi -done -if [ ! -d "hdl" ]; then - echo "HDL clone failed" - exit 1 -fi - - -# Get required vivado version needed for HDL -if [ -f "hdl/library/scripts/adi_ip.tcl" ]; then - TARGET="hdl/library/scripts/adi_ip.tcl" -else - TARGET="hdl/library/scripts/adi_ip_xilinx.tcl" -fi -VER=$(awk '/set REQUIRED_VIVADO_VERSION/ {print $3}' $TARGET | sed 's/"//g') -echo "Required Vivado version ${VER}" -VIVADOFULL=${VER} -if [ ${#VER} = 8 ] -then -VER=${VER:0:6} -fi -VIVADO=${VER} - -# Setup -source /opt/Xilinx/Vivado/$VIVADO/settings64.sh - -# Update build scripts and force vivado versions -cp scripts/adi_ip.tcl hdl/library/scripts/ -VERTMP=$(awk '/set REQUIRED_VIVADO_VERSION/ {print $3}' hdl/library/scripts/adi_ip.tcl | sed 's/"//g') -grep -rl ${VERTMP} hdl/library/scripts | xargs sed -i -e "s/${VERTMP}/${VIVADOFULL}/g" - -# Update relative paths -FILES=$(grep -lrnw hdl/projects -e "\.\.\/common" | grep -v Makefile) -for f in $FILES -do - echo "Updating relative paths of: $f" - DEVICE=$(echo "$f"| cut -d "/" -f 3) - STR="\$ad_hdl_dir\/projects\/$DEVICE" - sed -i "s/\.\.\/common/$STR\/common/g" "$f" -done - -# Rename .prj files since MATLAB ignores then during packaging -FILES=$(grep -lrn hdl/projects/common -e '.prj' | grep -v Makefile | grep -v .git) -for f in $FILES -do - echo "Updating prj reference in: $f" - sed -i "s/\.prj/\.mk/g" "$f" -done -FILES=$(find hdl/projects/common -name "*.prj") -for f in $FILES -do - DEST="${f::-3}mk" - echo "Renaming: $f to $DEST" - mv "$f" "$DEST" -done - -# Remove intel -rm -rf hdl/projects/common/intel -rm -rf hdl/library/intel - -# Remove references to GHDL crap -wget https://raw.githubusercontent.com/analogdevicesinc/hdl/hdl_2018_r2/library/scripts/adi_env.tcl -mv adi_env.tcl hdl/library/scripts/ -cp scripts/adi_env.tcl hdl/projects/scripts/ - -cp scripts/adi_project_xilinx.tcl hdl/projects/scripts/ -cp scripts/adi_ip_xilinx.tcl hdl/library/scripts/ - -# Update cores to move relative paths locally -sed -i 's/add_files/add_files\ -copy_to\ \[pwd\]\ -force/g' hdl/library/jesd204/axi_jesd204_common/axi_jesd204_common_ip.tcl - -# Update new folder names -sed -i 's/util_cdc/analog_lib.com_user_util_cdc_1.0/g' hdl/projects/common/xilinx/adi_fir_filter_bd.tcl -sed -i 's/util_fir_int/analog_lib.com_user_util_fir_int_1.0/g' hdl/projects/adrv9009/common/adrv9009_bd.tcl -sed -i 's/util_fir_int/analog_lib.com_user_util_fir_int_1.0/g' hdl/projects/adrv9371x/common/adrv9371x_bd.tcl - -# Pack IP cores -pwd -echo "Starting IP core packaging" -#vivado -verbose -mode batch -source scripts/pack_all_ips.tcl > /dev/null 2>&1 -vivado -verbose -mode batch -source scripts/pack_all_ips.tcl > log.txt - -# Repack i2s and i2c cores to include xml files -cd hdl/library/axi_i2s_adi/ -pwd -ls -#unzip analog.com_user_axi_i2s_adi_1.0.zip -d tmp -unzip analog_lib.com_user_axi_i2s_adi_1.0.zip -d tmp -#rm analog.com_user_axi_i2s_adi_1.0.zip -rm analog_lib.com_user_axi_i2s_adi_1.0.zip -ls -cp *.xml tmp/ -cd tmp -#zip -r analog.com_user_axi_i2s_adi_1.0.zip * -zip -r analog_lib.com_user_axi_i2s_adi_1.0.zip * -#cp analog.com_user_axi_i2s_adi_1.0.zip ../ -cp analog_lib.com_user_axi_i2s_adi_1.0.zip ../ -cd ../../../.. - -pwd - -cd hdl/library/util_i2c_mixer/ -#unzip analog.com_user_util_i2c_mixer_1.0.zip -d tmp/ -unzip analog_lib.com_user_util_i2c_mixer_1.0.zip -d tmp/ -#rm analog.com_user_util_i2c_mixer_1.0.zip -rm analog_lib.com_user_util_i2c_mixer_1.0.zip -cp *.xml tmp/ -cd tmp -#zip -r analog.com_user_util_i2c_mixer_1.0.zip * -zip -r analog_lib.com_user_util_i2c_mixer_1.0.zip * -#cp analog.com_user_util_i2c_mixer_1.0.zip ../ -cp analog_lib.com_user_util_i2c_mixer_1.0.zip ../ -cd ../../../.. - -pwd - -# Rename zips so they do not overwrite one another -cd hdl/library/jesd204 -FILES=$(find . -name "*.zip") -for f in $FILES -do - M=${f:2} - mv -- "$M" . -done -cd ../../.. - -#cd hdl/library/jesd204 -#FILES=$(find . -name "*.zip") -#for f in $FILES -#do -# echo "Renaming $f" -# M=${f:2} -# echo "Repacking $M" -# FN=${M::-4} -# unzip $M -d $FN -# mv -- "$FN" "jesd204_${FN}" -# cd "jesd204_${FN}" -# zip -r "jesd204_${FN}.zip" * -# cd .. -# mv "jesd204_${FN}/jesd204_${FN}.zip" . -# rm -rf "jesd204_${FN}" -# rm $M -#done -#cd ../../.. - -cd hdl/library/xilinx -FILES=$(find . -name "*.zip") -for f in $FILES -do - M=${f:2} - mv -- "$M" . -done -cd ../../.. - -#cd hdl/library/xilinx -#FILES=$(find . -name "*.zip") -#for f in $FILES -#do -# echo "Renaming $f" -# M=${f:2} -# echo "Repacking $M" -# FN=${M::-4} -# unzip $M -d $FN -# mv -- "$FN" "xilinx_${FN}" -# cd "xilinx_${FN}" -# zip -r "xilinx_${FN}.zip" * -# cd .. -# mv "xilinx_${FN}/xilinx_${FN}.zip" . -# rm -rf "xilinx_${FN}" -# rm $M -#done -#cd ../../.. - - -# Move all cores -echo "Moving all cores" -vivado -mode batch -source scripts/copy_all_packed_ips.tcl || true - -cp -r hdl/library/util_pack/*.zip hdl/library/ -cp -r hdl/library/jesd204/*.zip hdl/library/ -cp -r hdl/library/xilinx/*.zip hdl/library/ -cp -r hdl/projects/common common -cp -r hdl/projects/scripts/adi_board.tcl . - -mv hdl/projects projects_premerge -# Remove pluto since its manually updated -rm -rf projects_premerge/pluto -cp -r projects hdl/ -cp -R projects_premerge/* hdl/projects/ -rm -rf projects_premerge - -cp -R common/* hdl/projects/common/ -rm -rf common -mv adi_board.tcl hdl/projects/scripts/ - -# Update tcl scripts and additional IP cores (MUX) -cp scripts/adi_project.tcl hdl/projects/scripts/ -cp scripts/adi_build.tcl hdl/projects/scripts/ -cp ip/*.zip hdl/library/ - -# Update vivado version in MATLAB API and build script -DEFAULT_V_VERSION='2017.4' -cd .. -echo "SED 1" -grep -rl ${DEFAULT_V_VERSION} hdl/vendor/AnalogDevices/+AnalogDevices | grep -v MODEM | xargs sed -i "s/${DEFAULT_V_VERSION}/$VIVADO/g" -cd CI -echo "SED 2" -grep -rl ${DEFAULT_V_VERSION} hdl/projects/scripts | xargs sed -i "s/${DEFAULT_V_VERSION}/$VIVADOFULL/g" - -# Remove extra projects -FILES=$(find hdl/projects) -for f in $FILES -do - if [[ "$f" == 'adrv9009' ]]; then - continue - elif [[ "$f" == 'adrv9371x' ]]; then - continue - elif [[ "$f" == 'fmcomms2' ]]; then - continue - elif [[ "$f" == 'fmcomms5' ]]; then - continue - elif [[ "$f" == 'pluto' ]]; then - continue - elif [[ "$f" == 'adrv9001' ]]; then - continue - elif [[ "$f" == 'adrv9361z7035' ]]; then - continue - elif [[ "$f" == 'adrv9364z7020' ]]; then - continue - fi - rm -rf "hdl/projects/$f" - -done - -# Remove git directory move to bsp folder -rm -fr hdl/.git* -TARGET="../hdl/vendor/AnalogDevices/vivado" -if [ -d "$TARGET" ]; then - rm -rf "$TARGET" -fi -cp -r hdl $TARGET - - -# Cleanup -rm vivado_* -rm vivado.jou -rm vivado.log -rm -rf hdl diff --git a/CI/scripts/copy_all_packed_ips.tcl b/CI/scripts/copy_all_packed_ips.tcl deleted file mode 100644 index b8132f3..0000000 --- a/CI/scripts/copy_all_packed_ips.tcl +++ /dev/null @@ -1,74 +0,0 @@ - - -proc copy_all_packed_ips { DEST_FOLDER } { - - #set WD [pwd] - #set DEST_FOLDER D:/Work/hdlbsp-master/vendor/AnalogDevices/vivado/library - #set DEST_FOLDER $WD - - set folder_list [glob -types d *] - foreach dir $folder_list { - puts "$dir" - cd $dir - - if {[catch {set files_list [glob *]}]} { - cd .. - continue - } - - foreach file $files_list { - set idx [string first .zip $file 1] - if {$idx != -1} { - file copy -force $file $DEST_FOLDER/$file - puts $file - } - } - cd .. - - # Don't remove these folders - if {$dir=="common"} {continue} - if {$dir=="interfaces"} {continue} - if {$dir=="prcfg"} {continue} - if {$dir=="scripts"} {continue} - if {$dir=="xilinx"} {continue} - if {$dir=="jesd204"} {continue} - if {$dir=="spi_engine"} {continue} - if {$dir=="util_pack"} {continue} - file delete -force -- $dir - - - } - -} - -cd hdl - -# Move main library core zips -cd library -set DEST [pwd] -puts $DEST -copy_all_packed_ips $DEST - -# Move Xilinx core zips -cd xilinx -set DEST [pwd] -copy_all_packed_ips $DEST -cd .. - -# Move jesd204 core zips -cd jesd204 -set DEST [pwd] -copy_all_packed_ips $DEST -cd .. - -# Move spi_engine core zips -cd spi_engine -set DEST [pwd] -copy_all_packed_ips $DEST - -# Move util_pack core zips -cd util_pack -set DEST [pwd] -copy_all_packed_ips $DEST - -cd ../../.. diff --git a/CI/scripts/dockermake b/CI/scripts/dockermake deleted file mode 100644 index 06c9322..0000000 --- a/CI/scripts/dockermake +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -docker build . -t matlabci -f CI/scripts/Docker -docker run --rm -e "INCLUDE_EXAMPLES=$INCLUDE_EXAMPLES" -e "BOARD=$BOARD" -e "LM_LICENSE_FILE=$LM_LICENSE_FILE" -e "XILINXD_LICENSE_FILE=$XILINXD_LICENSE_FILE" -e "MLRELEASE=$MLRELEASE" -e "HDLBRANCH=$HDLBRANCH" -v "$(pwd):/work" -v /mlhsp:/mlhspro:ro -v /usr/local/MATLAB:/usr/local/MATLAB -v /root/.matlab:/root/.matlabro:ro -v /root/.Xilinx:/root/.Xilinxro:ro -v /opt/Xilinx:/opt/Xilinx --mac-address="$ADDR" matlabci /bin/bash -c "cd /work && chmod +x CI/scripts/setupDocker.sh && ./CI/scripts/setupDocker.sh && make -C CI/scripts '$@'" diff --git a/CI/scripts/genTlbx.m b/CI/scripts/genTlbx.m deleted file mode 100644 index c95c2fb..0000000 --- a/CI/scripts/genTlbx.m +++ /dev/null @@ -1,96 +0,0 @@ -function genTlbx(examples) - -if nargin==0 - examples = 1; -end - -version = '21.2.1'; -ml = ver('MATLAB'); -ml = ml.Release(2:end-1); -uuid = matlab.lang.internal.uuid; - -%% -cd(fileparts((mfilename('fullpath')))); -cd('../..'); -p = pwd; -cd(fileparts((mfilename('fullpath')))); - -if examples - fid = fopen('bsp.tmpl','r'); -else - fid = fopen('bsp_noexamples.tmpl','r'); -end -f=fread(fid,'*char')'; -fclose(fid); - -f = strrep(f,'__REPO-ROOT__',p); -f = strrep(f,'__VERSION__',version); -f = strrep(f,'__ML-RELEASE__',ml); -f = strrep(f,'__UUID__',uuid); - -fid = fopen('../../bsp.prj','w'); -fprintf(fid,'%s',f); -fclose(fid); - -cd('../..'); -addpath(genpath(matlabshared.supportpkg.getSupportPackageRoot)); -addpath(genpath('.')); -rmpath(genpath('.')); -if examples - ps = {'doc','examples'}; -else - ps = {'doc'}; -end -paths = ''; -for p = ps - pp = genpath(p{:}); - ppF = pp; - pp = pp(1:end-1); - pp = strrep(pp,':',''); - paths = [paths,['',pp,'']]; %#ok - addpath(ppF); -end -rehash -projectFile = 'bsp.prj'; -currentVersion = matlab.addons.toolbox.toolboxVersion(projectFile); -if examples - outputFile = ['AnalogDevicesPrecisionToolbox_v',currentVersion]; -else - outputFile = ['AnalogDevicesPrecisionToolbox_noexamples_v',currentVersion]; -end -matlab.addons.toolbox.packageToolbox(projectFile,outputFile) - -if ~usejava('desktop') - %% Update toolbox paths - mkdir other - movefile([outputFile,'.mltbx'], ['other/',outputFile,'.zip']); - cd other - unzip([outputFile,'.zip'],'out'); - cd('out') - cd('metadata'); - fid = fopen('configuration.xml','r'); - f=fread(fid,'*char')'; - fclose(fid); - - s = ''; - sections = strsplit(f,s); - s1 = sections{1}; - s2 = sections{2}; - newfile = [s1,paths,s,s2]; - - fid = fopen('configuration.xml','w'); - fprintf(fid,'%s',newfile); - fclose(fid); - - %% Repack - cd('..'); - zip([outputFile,'.zip'], '*'); - movefile([outputFile,'.zip'],['../../',outputFile,'.mltbx']); - cd('../..'); - rmdir('other','s'); -end - -delete bsp.prj - - - diff --git a/CI/scripts/genTlbx2.m b/CI/scripts/genTlbx2.m deleted file mode 100644 index 4c83292..0000000 --- a/CI/scripts/genTlbx2.m +++ /dev/null @@ -1,101 +0,0 @@ -function genTlbx2(examples) - -if nargin==0 - examples = 0; -end - -% Lookup versioning info from adi.Version -cwd = pwd; -parts = strsplit(mfilename('fullpath'),filesep); -tbroot = strjoin(parts(1:end-3),filesep); -cd(tbroot); -v = adi.Version; -uuid = matlab.lang.internal.uuid; -cd(cwd); - -%% -cd(fileparts((mfilename('fullpath')))); -cd('../..'); -p = pwd; -cd(fileparts((mfilename('fullpath')))); - -fid = fopen('bsp.tmpl','r'); -f=fread(fid,'*char')'; -fclose(fid); - -f = strrep(f,'__REPO-ROOT__',p); -f = strrep(f,'__VERSION__',v.Release); -f = strrep(f,'__ML-RELEASE__',v.MATLAB); -f = strrep(f,'__APP-NAME__',v.AppName); -f = strrep(f,'__EXAMPLES-DIR__',v.ExamplesDir); -f = strrep(f,'__UUID__',uuid); - -fid = fopen('../../bsp.prj','w'); -fprintf(fid,'%s',f); -fclose(fid); - -cd('../..'); -addpath(genpath(matlabshared.supportpkg.getSupportPackageRoot)); -addpath(genpath('.')); -rmpath(genpath('.')); -if examples - ps = {'doc',v.ExamplesDir}; -else - ps = {'doc'}; -end -if isprop(v,'HasHDL') && v.HasHDL - ps = [ps(:)',{'hdl'}]; -end - -paths = ''; -for p = ps - pp = genpath(p{:}); - ppF = pp; - pp = pp(1:end-1); - pp = strrep(pp,':',''); - paths = [paths,['',pp,'']]; %#ok - addpath(ppF); -end -rehash -projectFile = 'bsp.prj'; -currentVersion = matlab.addons.toolbox.toolboxVersion(projectFile); -if examples - outputFile = sprintf('AnalogDevices%s_v%s',v.ToolboxName,currentVersion); -else - outputFile = sprintf('AnalogDevices%s_noexamples_v%s',v.ToolboxName,currentVersion); -end -matlab.addons.toolbox.packageToolbox(projectFile,outputFile) - -if ~usejava('desktop') - %% Update toolbox paths - mkdir other - movefile([outputFile,'.mltbx'], ['other/',outputFile,'.zip']); - cd other - unzip([outputFile,'.zip'],'out'); - cd('out') - cd('metadata'); - fid = fopen('configuration.xml','r'); - f=fread(fid,'*char')'; - fclose(fid); - - s = ''; - sections = strsplit(f,s); - s1 = sections{1}; - s2 = sections{2}; - newfile = [s1,paths,s,s2]; - - fid = fopen('configuration.xml','w'); - fprintf(fid,'%s',newfile); - fclose(fid); - - %% Repack - cd('..'); - zip([outputFile,'.zip'], '*'); - movefile([outputFile,'.zip'],['../../',outputFile,'.mltbx']); - cd('../..'); - rmdir('other','s'); -end - -% delete bsp.prj - - diff --git a/CI/scripts/linter.m b/CI/scripts/linter.m deleted file mode 100644 index 4a26bff..0000000 --- a/CI/scripts/linter.m +++ /dev/null @@ -1,23 +0,0 @@ -clc; -ignoreFolders = {'CI','doc','test'}; -cd ../.. -d = pwd; -cd .. -addpath(genpath(d)); -cd(d); - -files = dir('**/*.m'); -for file = 1:length(files) - if contains(files(file).folder,ignoreFolders) - continue; - end - mfile = fullfile(files(file).folder,files(file).name); - rpt = mlint(mfile); - if ~isempty(rpt) - disp(mfile); - for l = 1:length(rpt) - disp([num2str(rpt(l).line) ': ' rpt(l).message]); - end - end -end - diff --git a/CI/scripts/pack_all_ips.tcl b/CI/scripts/pack_all_ips.tcl deleted file mode 100644 index 271533c..0000000 --- a/CI/scripts/pack_all_ips.tcl +++ /dev/null @@ -1,58 +0,0 @@ - -# Create zip of IP cores -proc pack_ip_core {sub} { - - set folder_list [glob -types d *] - - foreach dir $folder_list { - puts "$dir" - cd $dir - - if {[catch {set fp [open ${dir}_ip.tcl r]}]} { - cd .. - continue - } - close $fp - - set fp [open ${dir}_ip.tcl a+] - puts -nonewline $fp "ipx::archive_core -verbose {analog_${sub}.com_user_" - puts -nonewline $fp "$dir" - puts -nonewline $fp "_1.0.zip} \[ipx::current_core\]" - close $fp - - source ./${dir}_ip.tcl - - cd .. - } -} - -source hdl/library/scripts/adi_ip.tcl -source hdl/library/scripts/adi_env.tcl - -cd hdl - -# Pack main library cores -cd library -pack_ip_core "lib" - -# Pack Xilinx cores -cd xilinx -pack_ip_core "xilinx" -cd .. - -# Pack JESD cores -cd jesd204 -pack_ip_core "jesd" -cd .. - -# Pack spi_engine cores -cd spi_engine -pack_ip_core "spi_engine" -cd .. - -# Pack pack cores -cd util_pack -pack_ip_core "util_pack" -cd .. - -cd ../../ diff --git a/CI/scripts/ports.json b/CI/scripts/ports.json deleted file mode 100644 index 278ae32..0000000 --- a/CI/scripts/ports.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "ad7380": { - "chip": "AD7380", - "complex": "false", - "fpga": [ - "zcu102" - ], - "supported_rd": [ - "rx" - ], - "ports": [ - { - "rx": [ - { - "input": "false", - "width": 1, - "name": "axi_ad9680_cpack/fifo_wr_en", - "type": "valid" - }, - { - "input": "true", - "width": 1, - "name": "axi_ad9680_tpl/adc_valid_0", - "type": "valid" - }, - { - "input": "false", - "width": 64, - "name": "axi_ad9680_cpack/fifo_wr_data_0", - "type": "data" - }, - { - "input": "false", - "width": 64, - "name": "axi_ad9680_cpack/fifo_wr_data_1", - "type": "data" - }, - { - "input": "true", - "width": 64, - "name": "axi_ad9680_tpl/adc_data_0", - "type": "data" - }, - { - "input": "true", - "width": 64, - "name": "axi_ad9680_tpl/adc_data_1", - "type": "data" - } - ] - } - ] - }, - "ad7768": { - "chip": "AD7768", - "complex": "false", - "fpga": [ - "zcu102" - ], - "supported_rd": [ - "rx" - ], - "ports": [ - { - "rx": [ - { - "input": "false", - "width": 1, - "name": "util_mxfe_cpack/fifo_wr_en", - "type": "valid" - }, - { - "input": "true", - "width": 1, - "name": "rx_mxfe_tpl_core/adc_valid_0", - "type": "valid" - }, - { - "input": "false", - "width": 16, - "name": "util_mxfe_cpack/fifo_wr_data_0", - "type": "data" - }, - { - "input": "false", - "width": 16, - "name": "util_mxfe_cpack/fifo_wr_data_1", - "type": "data" - }, - { - "input": "false", - "width": 16, - "name": "util_mxfe_cpack/fifo_wr_data_2", - "type": "data" - }, - { - "input": "false", - "width": 16, - "name": "util_mxfe_cpack/fifo_wr_data_3", - "type": "data" - }, - { - "input": "false", - "width": 16, - "name": "util_mxfe_cpack/fifo_wr_data_4", - "type": "data" - }, - { - "input": "false", - "width": 16, - "name": "util_mxfe_cpack/fifo_wr_data_5", - "type": "data" - }, - { - "input": "false", - "width": 16, - "name": "util_mxfe_cpack/fifo_wr_data_6", - "type": "data" - }, - { - "input": "false", - "width": 16, - "name": "util_mxfe_cpack/fifo_wr_data_7", - "type": "data" - }, - { - "input": "true", - "width": 16, - "name": "rx_mxfe_tpl_core/adc_data_0", - "type": "data" - }, - { - "input": "true", - "width": 16, - "name": "rx_mxfe_tpl_core/adc_data_1", - "type": "data" - }, - { - "input": "true", - "width": 16, - "name": "rx_mxfe_tpl_core/adc_data_2", - "type": "data" - }, - { - "input": "true", - "width": 16, - "name": "rx_mxfe_tpl_core/adc_data_3", - "type": "data" - }, - { - "input": "true", - "width": 16, - "name": "rx_mxfe_tpl_core/adc_data_4", - "type": "data" - }, - { - "input": "true", - "width": 16, - "name": "rx_mxfe_tpl_core/adc_data_5", - "type": "data" - }, - { - "input": "true", - "width": 16, - "name": "rx_mxfe_tpl_core/adc_data_6", - "type": "data" - }, - { - "input": "true", - "width": 16, - "name": "rx_mxfe_tpl_core/adc_data_7", - "type": "data" - } - ] - } - ] - } -} diff --git a/CI/scripts/read_ports_json.py b/CI/scripts/read_ports_json.py deleted file mode 100644 index 7d6a695..0000000 --- a/CI/scripts/read_ports_json.py +++ /dev/null @@ -1,59 +0,0 @@ -import json - -# open ports.json file and parse -ports_json_file = 'ports.json' -with open(ports_json_file) as json_file: - ports = json.load(json_file) - - tmp_key = "m_name" - for key0 in ports.keys(): - for key1 in ports[key0]['ports'][0].keys(): - if (key1 == "rx"): - for ii in range(0, len(ports[key0]['ports'][0][key1])): - tmp_dict = ports[key0]['ports'][0][key1][ii] - if (tmp_dict['type'].lower() == "data"): - if (tmp_dict['input'] == "true"): - if tmp_key not in tmp_dict: - tmp_list = tmp_dict['name'].split("_") - last_ele = tmp_list[-1] - if (len(last_ele) == 1): - tmp_dict[tmp_key] = f"{ports[key0]['chip']} ADC Data {last_ele} IN" - elif (len(last_ele) == 2): - tmp_dict[tmp_key] = f"{ports[key0]['chip']} ADC Data {last_ele.upper()}" - elif (tmp_dict['input'] == "false"): - if tmp_key not in tmp_dict: - tmp_list = tmp_dict['name'].split("_") - last_ele = tmp_list[-1] - tmp_dict[tmp_key] = f"IP Data {last_ele.upper()} OUT" - elif (tmp_dict['type'].lower() == "valid"): - if (tmp_dict['input'] == "true"): - tmp_dict[tmp_key] = f"IP Valid Rx Data IN" - elif (tmp_dict['input'] == "false"): - tmp_dict[tmp_key] = f"IP Data Valid OUT" - ports[key0]['ports'][0][key1][ii] = tmp_dict - elif (key1 == "tx"): - for ii in range(0, len(ports[key0]['ports'][0][key1])): - tmp_dict = ports[key0]['ports'][0][key1][ii] - if (tmp_dict['type'].lower() == "data"): - if (tmp_dict['input'] == "false"): - if tmp_key not in tmp_dict: - tmp_list = tmp_dict['name'].split("_") - last_ele = tmp_list[-1] - if (len(last_ele) == 1): - tmp_dict[tmp_key] = f"{ports[key0]['chip']} DAC Data {last_ele} OUT" - elif (len(last_ele) == 2): - tmp_dict[tmp_key] = f"{ports[key0]['chip']} DAC Data {last_ele.upper()}" - elif (tmp_dict['input'] == "true"): - if tmp_key not in tmp_dict: - tmp_list = tmp_dict['name'].split("_") - last_ele = tmp_list[-1] - tmp_dict[tmp_key] = f"IP Data {last_ele.upper()} IN" - elif (tmp_dict['type'].lower() == "valid"): - if (tmp_dict['input'] == "true"): - tmp_dict[tmp_key] = f"IP Valid Tx Data IN" - elif (tmp_dict['input'] == "false"): - tmp_dict[tmp_key] = f"IP Load Tx Data OUT" - ports[key0]['ports'][0][key1][ii] = tmp_dict - -with open(ports_json_file, 'w') as json_file: - json.dump(ports, json_file, indent = 4) \ No newline at end of file diff --git a/CI/scripts/rename_common.py b/CI/scripts/rename_common.py deleted file mode 100644 index 46403c6..0000000 --- a/CI/scripts/rename_common.py +++ /dev/null @@ -1,35 +0,0 @@ -import os -import glob -import pathlib - -new_dir = "+commonrf" - -path = pathlib.Path(__file__).parent.resolve() - -path = os.path.split(path) -path = os.path.split(path[0])[0] - -files = glob.glob(os.path.join(path, "+adi", "**/*")) -if len(files) == 0: - print("No files found") - print("Did you clone all the submodules?") - exit(1) - -for file in files: - if os.path.isdir(file): - continue - with open(file, "r") as f: - content = f.read() - if "adi.common." in content: - content = content.replace("adi.common.", f"adi.{new_dir[1:]}.") - print("Updating:", file) - with open(file, "w") as f: - f.write(content) - -src = os.path.join(path, "+adi", "+common") -dst = os.path.join(path, "+adi", new_dir) -if os.path.isdir(src): - print("Renaming:", src, "->", dst) - os.rename(src, dst) -else: - print("No +common folder found. Maybe you already renamed it?") diff --git a/CI/scripts/setupDocker.sh b/CI/scripts/setupDocker.sh deleted file mode 100644 index eca338c..0000000 --- a/CI/scripts/setupDocker.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# This file is run inside of the docker container -echo "Copying HSP files" -cp -r /mlhspro /mlhsp -echo "Copying .matlab" -cp -r /root/.matlabro /root/.matlab -echo "Copying .Xilinx" -cp -r /root/.Xilinxro /root/.Xilinx diff --git a/CI/scripts/synth_designs.sh b/CI/scripts/synth_designs.sh deleted file mode 100644 index e99496d..0000000 --- a/CI/scripts/synth_designs.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -BOARD=$1 -MLFLAGS="-nodisplay -nodesktop -nosplash" - -if [ -z "$MLRELEASE" ] -then - MLRELEASE=R2021a -fi - -MLPATH=/usr/local/MATLAB - -cd ../.. -cp hdl/vendor/AnalogDevices/hdlcoder_board_customization.m test/hdlcoder_board_customization_local.m -sed -i "s/hdlcoder_board_customization/hdlcoder_board_customization_local/g" test/hdlcoder_board_customization_local.m -source /opt/Xilinx/Vivado/2019.1/settings64.sh -Xvfb :77 & -export DISPLAY=:77 -export SWT_GTK3=0 -source /opt/Xilinx/Vivado/2019.1/settings64.sh -$MLPATH/$MLRELEASE/bin/matlab $MLFLAGS -r "cd('test');runSynthTests('$BOARD');" -kill -9 `pidof Xvfb` diff --git a/CI/scripts/targeting_designs.sh b/CI/scripts/targeting_designs.sh deleted file mode 100644 index d284fe6..0000000 --- a/CI/scripts/targeting_designs.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -MLFLAGS="-nodisplay -nodesktop -nosplash" - -if [ -z "$MLRELEASE" ] -then - MLRELEASE=R2021a -fi -if [ -z "$DEMO" ] -then - DEMO="" -fi -echo "Testing demo: $DEMO" - -MLPATH=/usr/local/MATLAB - -cd ../.. -source /opt/Xilinx/Vivado/2019.1/settings64.sh -Xvfb :77 & -export DISPLAY=:77 -export SWT_GTK3=0 -source /opt/Xilinx/Vivado/2019.1/settings64.sh -$MLPATH/$MLRELEASE/bin/matlab $MLFLAGS -r "addpath(genpath('test'));addpath(genpath('deps'));runDemoTests('$DEMO');" -kill -9 `pidof Xvfb` From 7ff3bfdf865eaed7f70e52c775fde75bf33d7005 Mon Sep 17 00:00:00 2001 From: Stanca Pop Date: Mon, 26 Jun 2023 17:42:03 +0300 Subject: [PATCH 02/10] Add ToolboxCI submodule --- .gitmodules | 5 +++++ CI/scripts | 1 + 2 files changed, 6 insertions(+) create mode 160000 CI/scripts diff --git a/.gitmodules b/.gitmodules index 12bf1fc..73fe3bc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,8 @@ [submodule "+adi/+common"] path = +adi/+common url = https://github.com/analogdevicesinc/ToolboxCommon.git + branch = master +[submodule "CI/scripts"] + path = CI/scripts + url = https://github.com/analogdevicesinc/ToolboxCI.git + branch = master diff --git a/CI/scripts b/CI/scripts new file mode 160000 index 0000000..c1489a3 --- /dev/null +++ b/CI/scripts @@ -0,0 +1 @@ +Subproject commit c1489a3cf2781045900cb29e68a7b7c896200366 From b553558a24c95bed3da2c25fc3f570ac44958b76 Mon Sep 17 00:00:00 2001 From: Stanca Pop Date: Mon, 26 Jun 2023 17:55:03 +0300 Subject: [PATCH 03/10] Add cn0585_fmcz support --- +adi/+AD3552R/Base.m | 124 +++++++++++++++ +adi/+AD3552R/Tx.m | 88 +++++++++++ +adi/+CN0585/Base.m | 60 ++++++++ +adi/+CN0585/Rx.m | 21 +++ +adi/+CN0585/Tx0.m | 23 +++ +adi/+CN0585/Tx1.m | 22 +++ +adi/+LTC2387/Base.m | 72 +++++++++ +adi/+LTC2387/Rx.m | 73 +++++++++ +adi/Contents.m | 7 + +adi/Version.m | 3 +- CI/scripts_hdl/matlab_processors.tcl | 58 +++++++ CI/scripts_hdl/ports.json | 142 ++++++++++++++++++ .../+zed/hdlcoder_ref_design_customization.m | 22 +++ .../+cn0585_fmcz/+zed/plugin_board.m | 8 + .../+cn0585_fmcz/+zed/plugin_rd_rx.m | 5 + .../+cn0585_fmcz/+zed/plugin_rd_rxtx.m | 7 + .../+cn0585_fmcz/+zed/plugin_rd_tx.m | 7 + .../+util/ADIZynqSDRAttributeInfo.xml | 37 +++++ .../+util/ADIZynqSDRParameterInfo.xml | 13 ++ .../+AnalogDevices/+util/adizynqsdr.xml | 16 ++ .../+AnalogDevices/+util/extmodeHooksADI.m | 21 +++ .../AnalogDevices/+AnalogDevices/add_clocks.m | 22 +++ .../AnalogDevices/+AnalogDevices/add_io.m | 17 +++ .../+AnalogDevices/add_io_ports.m | 92 ++++++++++++ .../get_memory_axi_interface_info.m | 21 +++ .../AnalogDevices/+AnalogDevices/install.m | 61 ++++++++ .../+AnalogDevices/plugin_board.m | 42 ++++++ .../AnalogDevices/+AnalogDevices/plugin_rd.m | 90 +++++++++++ .../AnalogDevices/+AnalogDevices/uninstall.m | 7 + hdl/vendor/AnalogDevices/Contents.m | 2 + .../hdlcoder_board_customization.m | 15 ++ .../streaming/cn0585_fmcz/CN0585_streaming.m | 74 +++++++++ .../CN0585_streaming_axi4lite_read_write.m | 96 ++++++++++++ test/DemoTests.m | 74 +++++++++ test/NonHWTest.m | 28 ++++ test/adi_build.tcl | 79 ++++++++++ test/board_variants.m | 17 +++ test/build_design.m | 82 ++++++++++ test/runDemoTests.m | 44 ++++++ test/runInstallerTests.m | 48 ++++++ test/runNonHWTest.m | 39 +++++ test/runSynthTests.m | 68 +++++++++ test/setportmapping.m | 106 +++++++++++++ test/testModel.slx | Bin 0 -> 58678 bytes 44 files changed, 1952 insertions(+), 1 deletion(-) create mode 100755 +adi/+AD3552R/Base.m create mode 100755 +adi/+AD3552R/Tx.m create mode 100755 +adi/+CN0585/Base.m create mode 100755 +adi/+CN0585/Rx.m create mode 100755 +adi/+CN0585/Tx0.m create mode 100755 +adi/+CN0585/Tx1.m create mode 100755 +adi/+LTC2387/Base.m create mode 100755 +adi/+LTC2387/Rx.m create mode 100755 CI/scripts_hdl/matlab_processors.tcl create mode 100755 CI/scripts_hdl/ports.json create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_board.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rx.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rxtx.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_tx.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRAttributeInfo.xml create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRParameterInfo.xml create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+util/adizynqsdr.xml create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/+util/extmodeHooksADI.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/add_clocks.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/add_io.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/add_io_ports.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/get_memory_axi_interface_info.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/install.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/plugin_board.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/plugin_rd.m create mode 100755 hdl/vendor/AnalogDevices/+AnalogDevices/uninstall.m create mode 100755 hdl/vendor/AnalogDevices/Contents.m create mode 100755 hdl/vendor/AnalogDevices/hdlcoder_board_customization.m create mode 100644 pcx_examples/streaming/cn0585_fmcz/CN0585_streaming.m create mode 100755 pcx_examples/streaming/cn0585_fmcz/CN0585_streaming_axi4lite_read_write.m create mode 100755 test/DemoTests.m create mode 100755 test/NonHWTest.m create mode 100755 test/adi_build.tcl create mode 100755 test/board_variants.m create mode 100755 test/build_design.m create mode 100755 test/runDemoTests.m create mode 100755 test/runInstallerTests.m create mode 100755 test/runNonHWTest.m create mode 100644 test/runSynthTests.m create mode 100644 test/setportmapping.m create mode 100755 test/testModel.slx diff --git a/+adi/+AD3552R/Base.m b/+adi/+AD3552R/Base.m new file mode 100755 index 0000000..2604a01 --- /dev/null +++ b/+adi/+AD3552R/Base.m @@ -0,0 +1,124 @@ +classdef (Abstract) Base < ... + adi.common.RxTx & ... + matlabshared.libiio.base & ... + adi.common.Attribute + % adi.AD3552R.Tx Transmit data to the AD3552R high speed DAC + % The adi.AD3552R.Tx System object is a signal source that can send + % complex data from the AD3552R. + % + % tx = adi.AD3552R.Tx; + % tx = adi.AD3552R.Tx('uri','192.168.2.1'); + % + % AD3552R Datasheet + % + % See also adi.CN0585.Tx + + properties (Nontunable) + % SamplesPerFrame Samples Per Frame + % Number of samples per frame, specified as an even positive + % integer from 2 to 16,777,216. Using values less than 3660 can + % yield poor performance. + SamplesPerFrame = 2 ^ 15; + end + + properties (Nontunable, Hidden) + Timeout = Inf; + kernelBuffersCount = 2; + dataTypeStr = 'uint16'; + end + + properties (Abstract, Hidden, Constant) + Type + end + + properties (Hidden, Constant) + ComplexData = false; + end + + properties + % InputSource + % Lists all the available input sources of the DAC. + % Options are: 'adc_input', 'dma_input', 'ramp_input'. + % Example: InputSource = 'dma_input'; + InputSource = 'dma_input'; + end + + properties + % OutputRange + % Lists all the available voltage ranges of the output signal. + % Options are: '0/2.5V', '0/5V', '0/10V', '-5/+5V', '-10/+10V'. + % Example: OutputRange = '-10/+10V'; + OutputRange = '-10/+10V'; + end + + properties + InputSourceSet = matlab.system.StringSet({... + 'adc_input', 'dma_input', 'ramp_input'}) + OutputRangeSet = matlab.system.StringSet({... + '0/2.5V', '0/5V', '0/10V', '-5/+5V', '-10/+10V'}) + end + + methods + %% Constructor + function obj = Base(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@matlabshared.libiio.base(varargin{:}); + end + + % Check SamplesPerFrame + function set.SamplesPerFrame(obj, value) + validateattributes(value, {'double', 'single'}, ... + {'real', 'positive', 'scalar', 'finite', 'nonnan', 'nonempty', 'integer', '>', 0, '<', 2 ^ 20 + 1}, ... + '', 'SamplesPerFrame'); + obj.SamplesPerFrame = value; + end + + % Set/Get Input Source + function result = get.InputSource(obj) + result = obj.InputSource; + end + + function set.InputSource(obj, value) + obj.InputSource = value; + end + + % Set/Get Output Range + function result = get.OutputRange(obj) + result = obj.OutputRange; + end + + function set.OutputRange(obj, value) + obj.OutputRange = value; + end + + end + + %% API Functions + methods (Hidden, Access = protected) + + function icon = getIconImpl(obj) + icon = sprintf(['AD3552R', obj.Type]); + end + + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'AD3552R'; + end + + end + +end diff --git a/+adi/+AD3552R/Tx.m b/+adi/+AD3552R/Tx.m new file mode 100755 index 0000000..10e62d3 --- /dev/null +++ b/+adi/+AD3552R/Tx.m @@ -0,0 +1,88 @@ +classdef Tx < adi.common.Tx & adi.AD3552R.Base + % adi.AD3552R.Tx Transmit data to the AD3552R high speed DAC + % The adi.AD3552R.Tx System object is a signal source that can send + % complex data from the AD3552R. + % + % tx = adi.AD3552R.Tx; + % tx = adi.AD3552R.Tx('uri','192.168.2.1'); + % + % AD3552R Datasheet + % + % See also adi.CN0585.Tx + + properties (Constant) + % SamplingRate Sampling Rate + % Baseband sampling rate in Hz, specified as a scalar + % in samples per second. This value is constant. + SamplingRate = 15e6; + end + + properties (Hidden, Nontunable, Access = protected) + isOutput = true; + end + + properties (Nontunable, Hidden, Constant) + Type = 'Tx'; + end + + properties (Nontunable, Hidden) + devName = 'axi-ad3552r'; + phyDevName = 'axi-ad3552r'; + channel_names = {'voltage0', 'voltage1'}; + end + + properties + % StreamStatus + % Describes the status of the data streaming. + % Options are: 'start_stream_synced', 'start_stream', 'stop_stream'. + % Example: StreamStatus = 'stop_stream'; + StreamStatus = 'stop_stream'; + end + + properties (Hidden, Constant) + StreamStatusSet = matlab.system.StringSet({ ... + 'start_stream_synced', 'start_stream', 'stop_stream'}) + end + + methods + %% Constructor + function obj = Tx(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.AD3552R.Base(varargin{:}); + end + + %% Start or stop stream transfer + function set.StreamStatus(obj, value) + + if obj.ConnectedToDevice + obj.setDeviceAttributeRAW('stream_status', value); + else + error(['StreamStatus cannot be set before initialization, ']); + end + + obj.StreamStatus = value; + + end + + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'AD3552R'; + end + + end + +end diff --git a/+adi/+CN0585/Base.m b/+adi/+CN0585/Base.m new file mode 100755 index 0000000..3edc2f5 --- /dev/null +++ b/+adi/+CN0585/Base.m @@ -0,0 +1,60 @@ +classdef (Abstract, Hidden = true) Base < ... + adi.common.RxTx & ... + adi.common.Attribute & ... + matlabshared.libiio.base + %adi.CN0585.Base Class + % This class contains shared parameters and methods between TX and RX + % classes + + properties (Hidden) + iioOneBitADCDAC; + HDLSystemID + + end + + methods + %% Constructor + function obj = Base(varargin) + coder.allowpcode('plain'); + obj = obj@matlabshared.libiio.base(varargin{:}); + end + + function result = CheckMathWorksCore(obj) + result = contains(obj.HDLSystemID, "matlab"); + end + + end + + %% API Functions + methods (Hidden, Access = protected) + + function setupInit(obj) + + % GPIO CONTROLLER + + obj.iioOneBitADCDAC = getDev(obj, 'one-bit-adc-dac'); + obj.setAttributeBool('voltage0', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage1', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage2', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage3', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage4', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage5', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage6', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage7', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage8', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + obj.setAttributeBool('voltage9', 'raw', boolean(1), true, obj.iioOneBitADCDAC); + + % HDLSystemID SYSID STRING VALUE + + obj.HDLSystemID = obj.iio_context_get_attr_value(obj.iioCtx, 'hdl_system_id'); + + % UPDATED PARAMETERS + + obj.setDeviceAttributeRAW('input_source', obj.InputSource); + obj.setDeviceAttributeRAW('output_range', obj.OutputRange); + + end + + end + +end diff --git a/+adi/+CN0585/Rx.m b/+adi/+CN0585/Rx.m new file mode 100755 index 0000000..c9c8449 --- /dev/null +++ b/+adi/+CN0585/Rx.m @@ -0,0 +1,21 @@ +classdef Rx < adi.LTC2387.Rx + % adi.CN0585.Rx Receive data from the LTC2387 evaluation platform + % + % rx = adi.CN0585.Rx; + % rx = adi.CN0585.Rx('uri','192.168.2.1'); + % + % User Guide + % + % See also adi.LTC2387.Rx + + methods + %% Constructor + function obj = Rx(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.LTC2387.Rx(varargin{:}); + end + + end + +end diff --git a/+adi/+CN0585/Tx0.m b/+adi/+CN0585/Tx0.m new file mode 100755 index 0000000..50bc2c7 --- /dev/null +++ b/+adi/+CN0585/Tx0.m @@ -0,0 +1,23 @@ +classdef Tx0 < adi.AD3552R.Tx & adi.CN0585.Base + % adi.CN0585.Tx Transmit data from the AD3552R evaluation platform + % + % tx0 = adi.CN0585.Tx0; + % tx0 = adi.CN0585.Tx0('uri','192.168.2.1'); + % + % User Guide + % + % See also adi.AD3552R.Tx0 + + methods + %% Constructor + function obj = Tx0(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.AD3552R.Tx(varargin{:}); + obj.devName = 'axi-ad3552r-0'; + obj.phyDevName = 'axi-ad3552r-0'; + end + + end + +end diff --git a/+adi/+CN0585/Tx1.m b/+adi/+CN0585/Tx1.m new file mode 100755 index 0000000..352d5e5 --- /dev/null +++ b/+adi/+CN0585/Tx1.m @@ -0,0 +1,22 @@ +classdef Tx1 < adi.AD3552R.Tx & adi.CN0585.Base + % adi.CN0585.Tx Transmit data from the AD3552R evaluation platform + % + % tx1 = adi.CN0585.Tx1; + % tx1 = adi.CN0585.Tx1('uri','192.168.2.1'); + % + % User Guide + % + % See also adi.AD3552R.Tx1 + + methods + %% Constructor + function obj = Tx1(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.AD3552R.Tx(varargin{:}); + obj.devName = 'axi-ad3552r-1'; + obj.phyDevName = 'axi-ad3552r-1'; + end + end + +end diff --git a/+adi/+LTC2387/Base.m b/+adi/+LTC2387/Base.m new file mode 100755 index 0000000..cd1badb --- /dev/null +++ b/+adi/+LTC2387/Base.m @@ -0,0 +1,72 @@ +classdef (Abstract) Base < ... + adi.common.RxTx & ... + adi.common.Attribute & ... + matlabshared.libiio.base + %LTC2387 Base Class + + properties (Nontunable) + %SamplesPerFrame Samples Per Frame + % Number of samples per frame, specified as an even positive + % integer from 2 to 16,777,216. Using values less than 3660 can + % yield poor performance. + SamplesPerFrame = 2^15; + end + + properties(Nontunable, Hidden) + Timeout = Inf; + kernelBuffersCount = 2; + dataTypeStr = 'int64'; + end + + properties (Abstract, Hidden, Constant) + Type + end + + + properties (Hidden, Constant) + ComplexData = false; + end + + methods + %% Constructor + function obj = Base(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@matlabshared.libiio.base(varargin{:}); + end + % Check SamplesPerFrame + function set.SamplesPerFrame(obj, value) + validateattributes( value, { 'double','single' }, ... + { 'real', 'positive','scalar', 'finite', 'nonnan', 'nonempty','integer','>',0,'<',2^20+1}, ... + '', 'SamplesPerFrame'); + obj.SamplesPerFrame = value; + end + end + + %% API Functions + methods (Hidden, Access = protected) + + function icon = getIconImpl(obj) + icon = sprintf(['LTC2387 ',obj.Type]); + end + + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'LTC2387'; + end + + end +end diff --git a/+adi/+LTC2387/Rx.m b/+adi/+LTC2387/Rx.m new file mode 100755 index 0000000..0b1c6d6 --- /dev/null +++ b/+adi/+LTC2387/Rx.m @@ -0,0 +1,73 @@ +classdef Rx < adi.common.Rx & adi.LTC2387.Base & adi.common.Attribute + % adi.LTC2387.Rx Receive data from the LTC2387 high speed ADC + % The adi.LTC2387.Rx System object is a signal source that can receive + % complex data from the LTC2387. + % + % rx = adi.LTC2387.Rx; + % rx = adi.LTC2387.Rx('uri','192.168.2.1'); + % + % LTC2387 Datasheet + % + % See also adi.CN0585.Rx + + properties (Dependent) + %SamplingRate Sampling Rate + % Baseband sampling rate in Hz, specified as a scalar + % in samples per second. This value is constant + SamplingRate + end + properties (Hidden, Nontunable, Access = protected) + isOutput = false; + end + + properties(Nontunable, Hidden, Constant) + Type = 'Rx'; + end + + properties (Nontunable, Hidden) + devName = 'ltc2387'; + phyDevName = 'ltc2387'; + channel_names = {'voltage0','voltage1','voltage2','voltage3'}; + end + + methods + %% Constructor + function obj = Rx(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.LTC2387.Base(varargin{:}); + end + function value = get.SamplingRate(obj) + if obj.ConnectedToDevice + value= obj.getAttributeLongLong('voltage0','sampling_frequency',false); + else + value = NaN; + end + end + end + + %% API Functions + methods (Hidden, Access = protected) + function setupInit(~) + %unused + end + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'LTC2387'; + end + + end +end diff --git a/+adi/Contents.m b/+adi/Contents.m index 735aea5..dfdc479 100644 --- a/+adi/Contents.m +++ b/+adi/Contents.m @@ -14,3 +14,10 @@ % AD4858 - ADC % AD2S1210 - Resolver-to-Digital Converter % AD4020 - ADC +% AD43552R - DAC +% LTC2387 - DAC +% +% Boards and Platforms +% ----------------------- +% CN0585 - FMC development board for precision data acquisition + diff --git a/+adi/Version.m b/+adi/Version.m index cffb464..f749edb 100644 --- a/+adi/Version.m +++ b/+adi/Version.m @@ -2,7 +2,8 @@ % Version % BSP Version information properties (Constant) - MATLAB = 'R2021b' + Vivado = '2022.2' + MATLAB = 'R2022a' Release = '21.2.1' AppName = 'Analog Devices, Inc. Precision Toolbox' ToolboxName = 'PrecisionToolbox' diff --git a/CI/scripts_hdl/matlab_processors.tcl b/CI/scripts_hdl/matlab_processors.tcl new file mode 100755 index 0000000..12427a1 --- /dev/null +++ b/CI/scripts_hdl/matlab_processors.tcl @@ -0,0 +1,58 @@ +proc preprocess_bd {project carrier rxtx} { + + puts "Preprocessing $project $carrier $rxtx" + + switch $project { + cn0585_fmcz { + # Disconnect the ADC PACK pins + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] + + + set sys_cstring "matlab $rxtx" + sysid_gen_sys_init_file $sys_cstring + + #Disconnect adc_valid + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_valid] + # Reconnect the adc_valid in the system + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins axi_ltc2387_dma/fifo_wr_en] + + if {$rxtx == "rx"} { + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins axi_ad3552r_0/data_in_a] + connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins axi_ad3552r_0/data_in_b] + connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins axi_ad3552r_1/data_in_a] + connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins axi_ad3552r_1/data_in_b] + } + + if {$rxtx == "tx"} { + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_0] + connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_1] + connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_2] + connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_3] + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_en] + } + + if {$rxtx == "tx" || $rxtx == "rxtx"} { + + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_valid] + + # Connect dac valids together + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_0/valid_in_b] + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_a] + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_b] + } + switch $carrier { + zed { + set_property -dict [list CONFIG.NUM_MI {21}] [get_bd_cells axi_cpu_interconnect] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ACLK] [get_bd_pins axi_clkgen/clk_0] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ARESETN] [get_bd_pins sampling_clk_rstgen/peripheral_aresetn] + } + } + } + } +} diff --git a/CI/scripts_hdl/ports.json b/CI/scripts_hdl/ports.json new file mode 100755 index 0000000..51f6fb1 --- /dev/null +++ b/CI/scripts_hdl/ports.json @@ -0,0 +1,142 @@ +{ + "cn0585": { + "chip": "CN0585", + "complex": "true", + "fpga": [ + "zed" + ], + "supported_rd": [ + "rx", + "tx", + "rx & tx" + ], + "ports": [ + { + "rx": [ + { + "input": "false", + "width": 1, + "name": "util_ltc2387_adc_pack/fifo_wr_en", + "type": "valid" + }, + { + "input": "false", + "width": 16, + "name": "util_ltc2387_adc_pack/fifo_wr_data_0", + "type": "data" + }, + { + "input": "false", + "width": 16, + "name": "util_ltc2387_adc_pack/fifo_wr_data_1", + "type": "data" + }, + { + "input": "false", + "width": 16, + "name": "util_ltc2387_adc_pack/fifo_wr_data_2", + "type": "data" + }, + { + "input": "false", + "width": 16, + "name": "util_ltc2387_adc_pack/fifo_wr_data_3", + "type": "data" + }, + { + "input": "true", + "width": 1, + "name": "axi_ltc2387_0/adc_valid", + "type": "valid" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_0/adc_data", + "type": "data" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_1/adc_data", + "type": "data" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_2/adc_data", + "type": "data" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_3/adc_data", + "type": "data" + } + ], + "tx": [ + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_0/adc_data", + "type": "data" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_1/adc_data", + "type": "data" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_2/adc_data", + "type": "data" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_3/adc_data", + "type": "data" + }, + { + "input": "true", + "width": 1, + "name": "axi_ltc2387_0/adc_valid", + "type": "valid" + }, + { + "input": "false", + "width": 16, + "name": "axi_ad3552r_0/data_in_a", + "type": "data" + }, + { + "input": "false", + "width": 16, + "name": "axi_ad3552r_0/data_in_b", + "type": "data" + }, + { + "input": "false", + "width": 1, + "name": "axi_ad3552r_0/valid_in_a", + "type": "valid" + }, + { + "input": "false", + "width": 16, + "name": "axi_ad3552r_1/data_in_a", + "type": "data" + }, + { + "input": "false", + "width": 16, + "name": "axi_ad3552r_1/data_in_b", + "type": "data" + } + ] + } + ] + } +} diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m new file mode 100755 index 0000000..8e2c2c9 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m @@ -0,0 +1,22 @@ +function [rd, boardName] = hdlcoder_ref_design_customization +% Reference design plugin registration file +% 1. The registration file with this name inside of a board plugin folder +% will be picked up +% 2. Any registration file with this name on MATLAB path will also be picked up +% 3. The registration file returns a cell array pointing to the location of +% the reference design plugins +% 4. The registration file also returns its associated board name +% 5. Reference design plugin must be a package folder accessible from +% MATLAB path, and contains a reference design definition file + +% Copyright 2013-2014 The MathWorks, Inc. + +rd = {... + 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_rx', ... + 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_tx', ... + 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_rxtx', ... + }; + +boardName = 'AnalogDevices CN0585 ZED'; + +end diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_board.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_board.m new file mode 100755 index 0000000..22b5cf4 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_board.m @@ -0,0 +1,8 @@ +function hP = plugin_board() +% Zynq Platform PCore +% Use Plugin API to create board plugin object + +% Copyright 2015 The MathWorks, Inc. + +% Call the common board definition function +hP = AnalogDevices.plugin_board('CN0585', 'ZED'); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rx.m new file mode 100755 index 0000000..002adf5 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rx.m @@ -0,0 +1,5 @@ +function hRD = plugin_rd_rx +% Reference design definition + +% Call the common reference design definition function +hRD = AnalogDevices.plugin_rd('cn0585','ZED', 'Rx'); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rxtx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rxtx.m new file mode 100755 index 0000000..dc334fc --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rxtx.m @@ -0,0 +1,7 @@ +function hRD = plugin_rd_rxtx +% Reference design definition + +% Copyright 2014-2015 The MathWorks, Inc. + +% Call the common reference design definition function +hRD = AnalogDevices.plugin_rd('cn0585','ZED', 'Rx & Tx'); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_tx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_tx.m new file mode 100755 index 0000000..ae6ae98 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_tx.m @@ -0,0 +1,7 @@ +function hRD = plugin_rd_tx +% Reference design definition + +% Copyright 2014-2015 The MathWorks, Inc. + +% Call the common reference design definition function +hRD = AnalogDevices.plugin_rd('cn0585', 'ZED', 'Tx'); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRAttributeInfo.xml b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRAttributeInfo.xml new file mode 100755 index 0000000..7c9a676 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRAttributeInfo.xml @@ -0,0 +1,37 @@ + + + + Analog Devices Zynq SDR + true + + $(MATLAB_ROOT)/rtw/c/src/ext_mode/common/rtiostream_interface.c + + $(ARM_CORTEX_A_ROOT_DIR)/src/rtiostream_tcpip.c + codertarget.zynq.internal.extmodeHooksADI(hObj,'setupfcn'); + + TCP/IP + + + + + + + + + + $(TARGET_ROOT)/src/axi4Lite.c + $(TARGET_ROOT)/include + ARM_PROJECT + ADI_ZYNQ_SDR_IPADDRESS + ZYNQ_USERNAME + ZYNQ_PASSWORD + + codertarget.zynq.internal.onAfterCodeGen + codertarget.zynq.internal.onBuildEntryHook + codertarget.zynq.internal.onHardwareSelect + + diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRParameterInfo.xml b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRParameterInfo.xml new file mode 100755 index 0000000..5965474 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRParameterInfo.xml @@ -0,0 +1,13 @@ + + + + Analog Devices Zynq SDR + + Clocking + + + + Build options + + + diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+util/adizynqsdr.xml b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/adizynqsdr.xml new file mode 100755 index 0000000..3df950a --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/adizynqsdr.xml @@ -0,0 +1,16 @@ + + + + Analog Devices Zynq SDR + ARM Cortex-A9 + ARM Cortex-A + ARM Compatible->ARM Cortex + + "$(ARM_CORTEX_A_ROOT_DIR)/ssh_download.bat" + "$(MATLAB_ROOT)/toolbox/idelink/foundation/hostapps" root analog $(ADI_ZYNQ_SDR_IPADDRESS) /home/analog/Downloads + + $(TARGET_ROOT)/registry/parameters/ADIZynqSDRParameterInfo.xml + $(TARGET_ROOT)/registry/attributes/ADIZynqSDRAttributeInfo.xml + + + diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+util/extmodeHooksADI.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/extmodeHooksADI.m new file mode 100755 index 0000000..a600f58 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/extmodeHooksADI.m @@ -0,0 +1,21 @@ +function extmodeHooksADI(hObj,hookpoint) + +% Copyright 2014-2015 The MathWorks, Inc. + +modelName = get(getModel(hObj),'Name'); +modelName = sprintf('%s.elf', modelName); +data = codertarget.data.getData(hObj); +h__z = zynq(data.RTOS); +h__z.IPAddress = getenv('ADI_ZYNQ_SDR_IPADDRESS'); +h__z.Username = 'root'; +h__z.Password = 'analog'; + +switch (lower(hookpoint)) + case 'preconnectfcn', + waitForAppToStart(h__z, modelName, 60); + case 'setupfcn' + checkConnection(h__z); + otherwise +end + +end diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/add_clocks.m b/hdl/vendor/AnalogDevices/+AnalogDevices/add_clocks.m new file mode 100755 index 0000000..1faebf9 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/add_clocks.m @@ -0,0 +1,22 @@ +function add_clocks(hRD,project,design) + +switch lower(project) + case 'cn0585' + switch(upper(design)) + case 'RX' + hRD.addClockInterface( ... + 'ClockConnection', 'axi_clkgen/clk_0', ... + 'ResetConnection', 'sampling_clk_rstgen/peripheral_aresetn'); + + case 'TX' + hRD.addClockInterface( ... + 'ClockConnection', 'axi_clkgen/clk_0', ... + 'ResetConnection', 'sampling_clk_rstgen/peripheral_aresetn'); + case 'RX & TX' + hRD.addClockInterface( ... + 'ClockConnection', 'axi_clkgen/clk_0', ... + 'ResetConnection', 'sampling_clk_rstgen/peripheral_aresetn'); + otherwise + error('Unknown reference design'); + end +end diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/add_io.m b/hdl/vendor/AnalogDevices/+AnalogDevices/add_io.m new file mode 100755 index 0000000..58f6341 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/add_io.m @@ -0,0 +1,17 @@ +function add_io(hRD,project,fpga,type) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Add AXI4 and AXI4-Lite slave interfaces +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +out = AnalogDevices.get_memory_axi_interface_info(fpga,lower(project)); +hRD.addAXI4SlaveInterface( ... + 'InterfaceConnection', out.InterfaceConnection, ... + 'BaseAddress', out.BaseAddress, ... + 'MasterAddressSpace', out.MasterAddressSpace); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Add Reference design interfaces +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +AnalogDevices.add_io_ports(hRD,lower(project),lower(type),lower(fpga)); + +end \ No newline at end of file diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/add_io_ports.m b/hdl/vendor/AnalogDevices/+AnalogDevices/add_io_ports.m new file mode 100755 index 0000000..645e5a4 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/add_io_ports.m @@ -0,0 +1,92 @@ +function root = add_io_ports(hRD,project,type,fpga) + +[filepath,~,~] = fileparts(mfilename('fullpath')); +fileName = fullfile(filepath,'ports.json'); +fid = fopen(fileName); +raw = fread(fid,inf); +str = char(raw'); +fclose(fid); +data = jsondecode(str); + +project = erase(project,'-'); +if ~contains(fields(data),project) + error(sprintf('No project found in database for %s',project)); +end + +root = getfield(data, project); + +if ~contains(root.supported_rd,type) + error(sprintf('No project found in database for %s',project)); +end + +if ~contains(root.fpga,fpga) + error(sprintf('No project found in database for %s',fpga)); +end + + +if contains(type,'rx') + process(hRD, root.ports.rx, 'rx'); +end +if contains(type,'tx') + process(hRD, root.ports.tx, 'tx'); +end + + +end + +function process(hRD, rtx, type) +count = [-1 -1]; +for i = 1:length(rtx) + rx = rtx(i); + if strcmpi(rx.type,'valid') + hRD.addInternalIOInterface( ... + 'InterfaceID', rx.m_name, ... + 'InterfaceType', inout(rx.input), ... + 'PortName', inout_pn(rx.input, type), ... + 'PortWidth', rx.width, ... + 'InterfaceConnection', rx.name, ... + 'IsRequired', false); + elseif strcmpi(rx.type,'data') + if strcmp(rx.input, 'true') + count(1)=count(1)+1; + else + count(2)=count(2)+1; + end + hRD.addInternalIOInterface( ... + 'InterfaceID', rx.m_name, ... + 'InterfaceType', inout(rx.input), ... + 'PortName', inout_pn_d(rx.input,count,type), ... + 'PortWidth', rx.width, ... + 'InterfaceConnection', rx.name, ... + 'IsRequired', false); + else + error(sprintf('Unknown port type %s',rx.type)); + end +end +end + +%% +function out = inout_pn_d(in,count,type) +if strcmp(in, 'true') + out = sprintf('dut_data_in_%d_%s',count(1), type); +else + out = sprintf('dut_data_out_%d_%s',count(2), type); +end +end +%% +function out = inout_pn(in, type) + if strcmp(in, 'true') + out = sprintf('dut_data_valid_in_%s', type); + else + out = sprintf('dut_data_valid_out_%s', type); + end +end +%% +function out = inout(in) +if strcmp(in, 'true') + out = 'IN'; +else + out = 'OUT'; +end +end + diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/get_memory_axi_interface_info.m b/hdl/vendor/AnalogDevices/+AnalogDevices/get_memory_axi_interface_info.m new file mode 100755 index 0000000..fb1328e --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/get_memory_axi_interface_info.m @@ -0,0 +1,21 @@ +function out = get_memory_axi_interface_info(fpga,project) + + +switch project + case 'cn0585' + switch fpga + case{'ZED'} + InterfaceConnection = 'axi_cpu_interconnect/M20_AXI'; + BaseAddress = '0x43C00000'; + MasterAddressSpace = 'sys_ps7/Data'; + otherwise + error(sprintf('Unknown Project FPGA %s/%s',project,fpga)); %#ok<*SPERR> + end + otherwise + error(sprintf('Unknown Project %s',project)); %#ok<*SPERR> +end + +out = struct('InterfaceConnection', InterfaceConnection, ... + 'BaseAddress', BaseAddress, ... + 'MasterAddressSpace', MasterAddressSpace); +end diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/install.m b/hdl/vendor/AnalogDevices/+AnalogDevices/install.m new file mode 100755 index 0000000..9337a51 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/install.m @@ -0,0 +1,61 @@ +function install(mode) +% AnalogDevices.install adds/removes AnalogDevices HDL BSPs + +% Copyright 2015 MathWorks, Inc. All Rights Reserved. + + if nargin == 0 + mode = 0; + end + + %% Initialization + % Determine where we're operating out of + vendorRootDir = fileparts(strtok(mfilename('fullpath'), '+')); + + % Add/remove the common contents + commonRootDir = fullfile(fileparts(fileparts(vendorRootDir)), 'common'); + olddir = cd(commonRootDir); + cleanup = onCleanup(@()cd(olddir)); + hdlbsp.install(mode); + + + % Add/remove the vendor contents + paths = {... + fullfile(vendorRootDir),... + }; + + hdlbsp.util.vendorInstall(mode,paths); + + % Copy the Zynq SDR target definition file into the support package + source = []; + destination = []; + zynqRootDir = codertarget.zynq.internal.getSpPkgRootDir; + armRootDir = codertarget.arm_cortex_a.internal.getSpPkgRootDir; + + zynqTargetDir = fullfile(zynqRootDir,'registry/targethardware'); + source = [source {fullfile(vendorRootDir, '/+AnalogDevices/+util/adizynqsdr.xml')}]; + destination = [destination {fullfile(zynqTargetDir, 'adizynqsdr.xml')}]; + + zynqTargetDir = fullfile(zynqRootDir,'registry/attributes'); + source = [source {fullfile(vendorRootDir, '/+AnalogDevices/+util/ADIZynqSDRAttributeInfo.xml')}]; + destination = [destination {fullfile(zynqTargetDir, 'ADIZynqSDRAttributeInfo.xml')}]; + + zynqTargetDir = fullfile(zynqRootDir,'registry/parameters'); + source = [source {fullfile(vendorRootDir, '/+AnalogDevices/+util/ADIZynqSDRParameterInfo.xml')}]; + destination = [destination {fullfile(zynqTargetDir, 'ADIZynqSDRParameterInfo.xml')}]; + + source = [source {fullfile(vendorRootDir, '/+AnalogDevices/+util/extmodeHooksADI.m')}]; + destination = [destination {fullfile(zynqRootDir, '/+codertarget/+zynq/+internal/extmodeHooksADI.m')}]; + + source = [source {fullfile(armRootDir,'ssh_download.bat')}]; + destination = [destination {fullfile(zynqRootDir, 'ssh_download.bat')}]; + + if(mode == 0) + for i = 1:length(source) + copyfile(char(source(:,i)), char(destination(:,i)), 'f'); + end + else + for i = 1:length(destination) + delete(char(destination(:,i))); + end + end +end \ No newline at end of file diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_board.m b/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_board.m new file mode 100755 index 0000000..7fa2607 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_board.m @@ -0,0 +1,42 @@ +function hB = plugin_board(project, board) +% Use Plugin API to create board plugin object + +if nargin < 2 + board = ""; +end +hB = hdlcoder.Board; + +pname = project; + +% Target Board Information +hB.BoardName = sprintf('AnalogDevices %s', upper(pname)); +if nargin > 1 + hB.BoardName = sprintf('%s %s', hB.BoardName, upper(board)); +end + +% FPGA Device +hB.FPGAVendor = 'Xilinx'; + +% Determine the device based on the board +switch lower(project) + + case {'cn0585'} + switch(upper(board)) + case 'ZED' + hB.FPGADevice = sprintf('xc7%s', 'z020'); + hB.FPGAPackage = 'clg484'; + hB.FPGASpeed = '-1'; + hB.FPGAFamily = 'Zynq'; + end + +end + +% Tool Info +hB.SupportedTool = {'Xilinx Vivado'}; + +% FPGA JTAG chain position +hB.JTAGChainPosition = 2; + +%% Add interfaces +% Standard "External Port" interface + diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_rd.m b/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_rd.m new file mode 100755 index 0000000..3ae31d6 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_rd.m @@ -0,0 +1,90 @@ +function hRD = plugin_rd(project, board, design) +% Reference design definition + +% Copyright 2014-2015 The MathWorks, Inc. + +pname = upper(project); +ppath = project; +if strcmpi(project, 'cn0585') + ppath = 'cn0585_fmcz'; +end + +% Construct reference design object +hRD = hdlcoder.ReferenceDesign('SynthesisTool', 'Xilinx Vivado'); + +% Create the reference design for the SOM-only +% This is the base reference design that other RDs can build upon +hRD.ReferenceDesignName = sprintf('%s %s (%s)', pname, upper(board), upper(design)); + +% Determine the board name based on the design +hRD.BoardName = sprintf('AnalogDevices %s %s', pname, upper(board)); + +% Tool information +hRD.SupportedToolVersion = {'2022.2'}; + +% Get the root directory +rootDir = fileparts(strtok(mfilename('fullpath'), '+')); + +% Design files are shared +hRD.SharedRD = true; +hRD.SharedRDFolder = fullfile(rootDir, 'vivado'); + +%% Set top level project pieces +hRD.addParameter( ... + 'ParameterID', 'project', ... + 'DisplayName', 'HDL Project Subfolder', ... + 'DefaultValue', lower(ppath)); + +hRD.addParameter( ... + 'ParameterID', 'carrier', ... + 'DisplayName', 'HDL Project Carrier', ... + 'DefaultValue', lower(board)); + + +%% Add custom design files +% add custom Vivado design +hRD.addCustomVivadoDesign( ... + 'CustomBlockDesignTcl', fullfile('projects', 'scripts', 'system_project_rxtx.tcl'), ... + 'CustomTopLevelHDL', fullfile('projects', lower(ppath), lower(board), 'system_top.v')); + +hRD.BlockDesignName = 'system'; + +% custom constraint files +hRD.CustomConstraints = {... + fullfile('projects', lower(ppath), lower(board), 'system_constr.xdc'), ... + fullfile('projects', 'common', lower(board), sprintf('%s_system_constr.xdc', lower(board))), ... + }; + +% custom source files +hRD.CustomFiles = {... + fullfile('projects')..., + fullfile('library')..., + fullfile('scripts')..., + }; + +hRD.addParameter( ... + 'ParameterID', 'ref_design', ... + 'DisplayName', 'Reference Type', ... + 'DefaultValue', lower(strrep(design, ' & ',''))); + +hRD.addParameter( ... + 'ParameterID', 'fpga_board', ... + 'DisplayName', 'FPGA Boad', ... + 'DefaultValue', upper(board)); + +hRD.addParameter( ... + 'ParameterID', 'preprocess', ... + 'DisplayName', 'Preprocess', ... + 'DefaultValue', 'off'); + +hRD.addParameter( ... + 'ParameterID', 'postprocess', ... + 'DisplayName', 'Postprocess', ... + 'DefaultValue', 'off'); + +%% Add interfaces +% add clock interface +AnalogDevices.add_clocks(hRD,project,design) + +%% Add IO +AnalogDevices.add_io(hRD,project,board,design); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/uninstall.m b/hdl/vendor/AnalogDevices/+AnalogDevices/uninstall.m new file mode 100755 index 0000000..ce1a433 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/uninstall.m @@ -0,0 +1,7 @@ +function uninstall +% AnalogDevices.uninstall removes AnalogDevices HDL BSPs + +% Copyright 2015 MathWorks, Inc. All Rights Reserved. + + AnalogDevices.install(1); +end diff --git a/hdl/vendor/AnalogDevices/Contents.m b/hdl/vendor/AnalogDevices/Contents.m new file mode 100755 index 0000000..9aa4ea5 --- /dev/null +++ b/hdl/vendor/AnalogDevices/Contents.m @@ -0,0 +1,2 @@ +% Precision Toolbox: Analog Devices, Inc +% Version 21.1.1 (R2021a) 3-Dec-2021 \ No newline at end of file diff --git a/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m b/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m new file mode 100755 index 0000000..d553377 --- /dev/null +++ b/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m @@ -0,0 +1,15 @@ +function r = hdlcoder_board_customization +% Board plugin registration file +% 1. Any registration file with this name on MATLAB path will be picked up +% 2. Registration file returns a cell array pointing to the location of +% the board plugins +% 3. Board plugin must be a package folder accessible from MATLAB path, +% and contains a board definition file + +% Copyright 2012-2013 The MathWorks, Inc. + +r = { ... + 'AnalogDevices.cn0585_fmcz.zed.plugin_board' ..., + }; +end +% LocalWords: Zynq ZC diff --git a/pcx_examples/streaming/cn0585_fmcz/CN0585_streaming.m b/pcx_examples/streaming/cn0585_fmcz/CN0585_streaming.m new file mode 100644 index 0000000..a9d9e81 --- /dev/null +++ b/pcx_examples/streaming/cn0585_fmcz/CN0585_streaming.m @@ -0,0 +1,74 @@ +% CN0585 Streaming example + +board_ip = 'local_board_ip'; +uri = cat(2, 'ip:', board_ip); + +% Describe the devices + +cn0585_device_rx = adi.CN0585.Rx('uri',uri); +cn0585_device_tx0 = adi.CN0585.Tx0('uri',uri); +cn0585_device_tx1 = adi.CN0585.Tx1('uri',uri); + +cn0585_device_tx0.EnableCyclicBuffers = true; +cn0585_device_tx1.EnableCyclicBuffers = true; + +cn0585_device_rx.BufferTypeConversionEnable = true; + +% Enable the channels to write data to (options are 1, 2 ) + +cn0585_device_tx0.EnabledChannels = [1, 2]; +cn0585_device_tx1.EnabledChannels = [1, 2]; + +% Enable the channels to read data from (options are 1, 2, 3 ,4 ) + +cn0585_device_rx.EnabledChannels = [1, 2, 3, 4]; + +% Generate the sinewave signal + +amplitude = 2 ^ 15; +sampFreq = cn0585_device_tx0.SamplingRate; +toneFreq = 1e3; +N = sampFreq / toneFreq; +x = linspace(-pi, pi, N).'; +sine_wave = amplitude * sin(x); + +% Continuously load data in the buffer and configure the GPIOs state +% (SetupInit Base file) +% DAC1 has to be updated and started first and then DAC0 in order to have syncronized data between devices + +cn0585_device_tx1([sine_wave, sine_wave]); +cn0585_device_tx0([sine_wave, sine_wave]); + +% Stream status available options: "start_stream_synced", "start_stream", "stop_stream" + +cn0585_device_tx1.StreamStatus = 'start_stream'; +cn0585_device_tx0.StreamStatus = 'start_stream'; + +% The data will be stored inside "data" variable + +data = cn0585_device_rx(); + +title('ADAQ23876 Channels'); +subplot(4, 1, 1); +plot(data(:, 1)); +ylabel('Channel A'); +subplot(4, 1, 2); +plot(data(:, 2)); +ylabel('Channel B'); +subplot(4, 1, 3); +plot(data(:, 3)); +ylabel('Channel C'); +subplot(4, 1, 4); +plot(data(:, 4)); +ylabel('Channel D'); +xlabel('Number of samples'); + +% Release the device + +cn0585_device_tx1.StreamStatus = 'stop_stream'; +cn0585_device_tx0.StreamStatus = 'stop_stream'; + +cn0585_device_tx1.release(); +cn0585_device_tx0.release(); + +cn0585_device_rx.release(); diff --git a/pcx_examples/streaming/cn0585_fmcz/CN0585_streaming_axi4lite_read_write.m b/pcx_examples/streaming/cn0585_fmcz/CN0585_streaming_axi4lite_read_write.m new file mode 100755 index 0000000..935eaa0 --- /dev/null +++ b/pcx_examples/streaming/cn0585_fmcz/CN0585_streaming_axi4lite_read_write.m @@ -0,0 +1,96 @@ +% CN0585 Streaming example for AXI4 Lite register read/write + +board_ip = 'local_board_ip'; +uri = cat(2, 'ip:', board_ip); + +% Describe the devices + +cn0585_device_rx = adi.CN0585.Rx('uri',uri); +cn0585_device_tx0 = adi.CN0585.Tx0('uri',uri); +cn0585_device_tx1 = adi.CN0585.Tx1('uri',uri); + +cn0585_device_tx0.EnableCyclicBuffers = true; +cn0585_device_tx1.EnableCyclicBuffers = true; + +cn0585_device_rx.BufferTypeConversionEnable = true; + +% Enable the channels to write data to (options are 1, 2) + +cn0585_device_tx0.EnabledChannels = [1, 2]; +cn0585_device_tx1.EnabledChannels = [1, 2]; + +% Enable the channels to read data from (options are 1, 2, 3 ,4) + +cn0585_device_rx.EnabledChannels = [1, 2, 3, 4]; + +write_reg = soc.libiio.aximm.WriteHost(devName = 'mwipcore0:mmwr-channel0', IPAddress = board_ip); % MathWorks IP Core Write channel +read_reg = soc.libiio.aximm.WriteHost(devName = 'mwipcore0:mmrd-channel1', IPAddress = board_ip); % MathWorks IP Core Read channel + +% Input source available options: 'adc_input', 'dma_input', 'ramp_input' + +cn0585_device_tx0.InputSource = 'dma_input'; +cn0585_device_tx1.InputSource = 'dma_input'; + +% Output range available options: '0/2.5V', '0/5V', '0/10V', '-5/+5V', '-10/+10V' + +cn0585_device_tx0.OutputRange = '-10/+10V'; +cn0585_device_tx1.OutputRange = '-10/+10V'; + +% Generate the sinewave signal + +amplitude = 2 ^ 15; +sampFreq = cn0585_device_tx0.SamplingRate; +toneFreq = 1e3; +N = sampFreq / toneFreq; +x = linspace(-pi, pi, N).'; +sine_wave = amplitude * sin(x); + +% Continuously load data in the buffer and configure the GPIOs state +% (SetupInit Base file) +% DAC1 has to be updated and started first and then DAC0 in order to have syncronized data between devices + +cn0585_device_tx1([sine_wave, sine_wave]); +cn0585_device_tx0([sine_wave, sine_wave]); + +% Stream status available options: "start_stream_synced", "start_stream", "stop_stream" + +cn0585_device_tx1.StreamStatus = 'start_stream'; +cn0585_device_tx0.StreamStatus = 'start_stream'; + +% The data will be stored inside "data" variable + +data = cn0585_device_rx(); + +if cn0585_device_tx0.CheckMathWorksCore() + + write_reg.writeReg(hex2dec('100'), 85); + write_reg.writeReg(hex2dec('104'), 22); + + fprintf('Read value from the 0x108 register is: %d \n', read_reg.readReg(hex2dec('108'))); + fprintf('Read value from the 0x10c register is: %d \n', read_reg.readReg(hex2dec('10c'))); +end + +title('ADAQ23876 Channels'); +subplot(4, 1, 1); +plot(data(:, 1)); +ylabel('Channel A'); +subplot(4, 1, 2); +plot(data(:, 2)); +ylabel('Channel B'); +subplot(4, 1, 3); +plot(data(:, 3)); +ylabel('Channel C'); +subplot(4, 1, 4); +plot(data(:, 4)); +ylabel('Channel D'); +xlabel('Number of samples'); + +% Release the device + +cn0585_device_tx1.StreamStatus = 'stop_stream'; +cn0585_device_tx0.StreamStatus = 'stop_stream'; + +cn0585_device_tx1.release(); +cn0585_device_tx0.release(); + +cn0585_device_rx.release(); diff --git a/test/DemoTests.m b/test/DemoTests.m new file mode 100755 index 0000000..a2f7d88 --- /dev/null +++ b/test/DemoTests.m @@ -0,0 +1,74 @@ +classdef DemoTests < matlab.uitest.TestCase + + properties + root = ''; + end + + methods(TestClassSetup) + function addpaths(testCase) + here = mfilename('fullpath'); + here = strsplit(here,'/'); + here = fullfile('/',here{1:end-2}); + testCase.root = here; + addpath(genpath(fullfile(here,'hdl'))); + end + function setupVivado(~) + v=ver('matlab'); Release = v.Release; + switch Release + case '(R2017a)' + vivado = '2016.2'; + case '(R2017b)' + vivado = '2017.4'; + case '(R2018b)' + vivado = '2017.4'; + case '(R2019a)' + vivado = '2018.2'; + case '(R2019b)' + vivado = '2018.2'; + case '(R2020a)' + vivado = '2018.2'; + case '(R2020b)' + vivado = '2018.2'; + case '(R2021a)' + vivado = '2018.2'; + case '(R2021b)' + vivado = '2021.1'; + case '(R2022a)' + vivado = '2022.2'; + end + if ispc + hdlsetuptoolpath('ToolName', 'Xilinx Vivado', ... + 'ToolPath', ['C:\Xilinx\Vivado\',vivado,'\bin\vivado.bat']); + elseif isunix + hdlsetuptoolpath('ToolName', 'Xilinx Vivado', ... + 'ToolPath', ['/opt/Xilinx/Vivado/',vivado,'/bin/vivado']); + end + + end + end + + methods(TestMethodTeardown) + function cleanup_hdl_prj(testCase) + dir = fullfile(testCase.root,'test','hdl_prj'); + if exist(dir, 'dir') + rmdir(fullfile(testCase.root,'test','hdl_prj'), 's'); + end + end + end + + methods(Test) + %function buildHDLDAQ2ZCU102_BOOTBIN(testCase) + % cd(fullfile(testCase.root,'test')); + % out = hdlworkflow_daq2_zcu102_rx('2018.2'); + % if ~isempty(out) + % disp(out.message); + % end + % % Check for BOOT.BIN + % if exist('hdl_prj/vivado_ip_prj/boot/BOOT.BIN', 'file') ~= 2 + % error('BOOT.BIN Failed'); + % end + %end + end + +end + diff --git a/test/NonHWTest.m b/test/NonHWTest.m new file mode 100755 index 0000000..4e04fc9 --- /dev/null +++ b/test/NonHWTest.m @@ -0,0 +1,28 @@ +classdef NonHWTest < matlab.unittest.TestCase + + properties(TestParameter) + rootClasses = {... + {'AD9081',{'Rx','Tx'}},... + {'AD9144',{'Tx'}},... + {'AD9152',{'Tx'}},... + {'AD9467',{'Rx'}},... + {'AD9680',{'Rx'}},... + {'DAQ2',{'Rx','Tx'}},... + {'QuadMxFE',{'Rx','Tx'}}... + }; + end + + methods (Test) + + function call_constructors(testCase,rootClasses) + for trx = rootClasses{2} + sdr = eval(['adi.',rootClasses{1},'.',trx{:},'()']); + testCase.assertEqual(class(sdr),['adi.',rootClasses{1},'.',trx{:}]); + end + end + + end + + +end + diff --git a/test/adi_build.tcl b/test/adi_build.tcl new file mode 100755 index 0000000..d4d155a --- /dev/null +++ b/test/adi_build.tcl @@ -0,0 +1,79 @@ +global fpga_board + +if {[info exists fpga_board]} { + puts "===========" + puts $fpga_board + puts "===========" +} else { + # Set to something not ZCU102 + set fpga_board "ZYNQ" +} + +# Build the project +update_compile_order -fileset sources_1 +reset_run impl_1 +reset_run synth_1 +launch_runs synth_1 +wait_on_run synth_1 +launch_runs impl_1 -to_step write_bitstream +wait_on_run impl_1 + +# Define local variables +set cdir [pwd] +set sdk_loc vivado_prj.sdk + +# Export the hdf +file delete -force $sdk_loc +file mkdir $sdk_loc +write_hw_platform -fixed -force -include_bit -file $sdk_loc/system_top.xsa + +# Close the Vivado project +close_project + +# Create the BOOT.bin +#exec xsdk -batch -source $cdir/projects/scripts/fsbl_build.tcl -tclargs $fpga_board -wait + +if {$fpga_board eq "ZCU102"} { + exec hsi -source $cdir/projects/scripts/pmufw_zynqmp.tcl + file copy -force $cdir/projects/scripts/fixmake.sh $cdir/fixmake.sh + exec chmod +x fixmake.sh + + #exec ./fixmake.sh + #cd pmufw + #exec make + #cd .. + if [catch "exec -ignorestderr ./fixmake.sh" ret opt] { + set makeRet [lindex [dict get $opt -errorcode] end] + puts "make returned with $makeRet" + } + if {[file exist pmufw/executable.elf] eq 0} { + puts "ERROR: pmufw not built" + return -code error 10 + } else { + puts "pmufw built correctly!" + } + + set vversion [version -short] + exec xsdk -batch -source $cdir/projects/scripts/fsbl_build_zynqmp.tcl $vversion + if {[file exist boot/BOOT.BIN] eq 0} { + puts "ERROR: BOOT.BIN not built" + return -code error 11 + } else { + puts "BOOT.BIN built correctly!" + } + +} else { + exec xsdk -batch -source $cdir/projects/scripts/fsbl_build_zynq.tcl + if {[file exist boot/BOOT.BIN] eq 0} { + puts "ERROR: BOOT.BIN not built" + return -code error 11 + } else { + puts "BOOT.BIN built correctly!" + } +} + +puts "------------------------------------" +puts "Embedded system build completed." +puts "You may close this shell." +puts "------------------------------------" +exit diff --git a/test/board_variants.m b/test/board_variants.m new file mode 100755 index 0000000..441c4ab --- /dev/null +++ b/test/board_variants.m @@ -0,0 +1,17 @@ +function r = board_variants +% Board plugin registration file +% 1. Any registration file with this name on MATLAB path will be picked up +% 2. Registration file returns a cell array pointing to the location of +% the board plugins +% 3. Board plugin must be a package folder accessible from MATLAB path, +% and contains a board definition file + +% Copyright 2023 The MathWorks, Inc. + +r = { ... + 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_rx', ... + 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_tx', ... + 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_rxtx', ... + }; +end +% LocalWords: Zynq ZC diff --git a/test/build_design.m b/test/build_design.m new file mode 100755 index 0000000..8930f65 --- /dev/null +++ b/test/build_design.m @@ -0,0 +1,82 @@ + +function out = build_design(config,ReferenceDesignName,vivado_version,mode,board_name,SynthesizeDesign,folder) + +%% Restore the Model to default HDL parameters +%hdlrestoreparams('testModel/HDL_DUT'); + +%% Set port mapping based on design configuration +mdl = setportmapping(mode,ReferenceDesignName,board_name); + +%% Model HDL Parameters + +%% Set Model mdl HDL parameters +hdlset_param(mdl, 'HDLSubsystem', [mdl,'/HDL_DUT']); +hdlset_param(mdl, 'ReferenceDesign', ReferenceDesignName); +hdlset_param(mdl, 'SynthesisTool', config.SupportedTool{:}); +hdlset_param(mdl, 'SynthesisToolChipFamily', config.FPGAFamily); +hdlset_param(mdl, 'SynthesisToolDeviceName', config.FPGADevice); +hdlset_param(mdl, 'SynthesisToolPackageName', config.FPGAPackage); +hdlset_param(mdl, 'SynthesisToolSpeedValue', config.FPGASpeed); +hdlset_param(mdl, 'TargetPlatform', config.BoardName); +hdlset_param(mdl, 'TargetLanguage', 'Verilog'); +hdlset_param(mdl, 'TargetDirectory', [folder,'\hdlsrc']); +hdlset_param(mdl, 'Workflow', 'IP Core Generation'); +hdlset_param([mdl,'/HDL_DUT'], 'ProcessorFPGASynchronization', 'Free running'); + +%% Workflow Configuration Settings +% Construct the Workflow Configuration Object with default settings +hWC = hdlcoder.WorkflowConfig('SynthesisTool','Xilinx Vivado','TargetWorkflow','IP Core Generation'); + +% Specify the top level project directory +hWC.ProjectFolder = folder; +hWC.ReferenceDesignToolVersion = vivado_version; +hWC.IgnoreToolVersionMismatch = true; +hWC.AllowUnsupportedToolVersion = true; + +% Set Workflow tasks to run +hWC.RunTaskGenerateRTLCodeAndIPCore = true; +hWC.RunTaskCreateProject = true; +hWC.RunTaskGenerateSoftwareInterfaceModel = false; +hWC.RunTaskBuildFPGABitstream = SynthesizeDesign; +hWC.RunTaskProgramTargetDevice = false; + +% Set properties related to 'RunTaskGenerateRTLCodeAndIPCore' Task +hWC.IPCoreRepository = ''; +hWC.GenerateIPCoreReport = false; + +% Set properties related to 'RunTaskCreateProject' Task +hWC.Objective = hdlcoder.Objective.None; +hWC.AdditionalProjectCreationTclFiles = ''; +hWC.EnableIPCaching = false; + +% Set properties related to 'RunTaskGenerateSoftwareInterfaceModel' Task +hWC.OperatingSystem = 'Linux'; + +% Set properties related to 'RunTaskBuildFPGABitstream' Task +hWC.RunExternalBuild = false; +%hWC.TclFileForSynthesisBuild = hdlcoder.BuildOption.Default; +%hWC.CustomBuildTclFile = ''; + +hWC.TclFileForSynthesisBuild = hdlcoder.BuildOption.Custom; +hWC.CustomBuildTclFile = '../hdl/vendor/AnalogDevices/vivado/projects/scripts/adi_build.tcl'; + +% Set properties related to 'RunTaskProgramTargetDevice' Task +%hWC.ProgrammingMethod = hdlcoder.ProgrammingMethod.Download; +%hWC.ProgrammingMethod = hdlcoder.ProgrammingMethod.Custom; + +% Validate the Workflow Configuration Object +hWC.validate; + +%% Run the workflow +try + hdlcoder.runWorkflow([mdl,'/HDL_DUT'], hWC, 'Verbosity', 'on'); + close_system(mdl, false); + bdclose('all'); + out = []; +catch ME + if SynthesizeDesign && exist([folder,'/vivado_ip_prj/boot/BOOT.BIN'],'file') + ME = []; + end + out = ME;%.identifier +end + diff --git a/test/runDemoTests.m b/test/runDemoTests.m new file mode 100755 index 0000000..e93f62d --- /dev/null +++ b/test/runDemoTests.m @@ -0,0 +1,44 @@ +function suite = runDemoTests(name) + +import matlab.unittest.TestRunner; +import matlab.unittest.TestSuite; +import matlab.unittest.plugins.TestReportPlugin; +import matlab.unittest.plugins.XMLPlugin +import matlab.unittest.plugins.DiagnosticsValidationPlugin + +suite = testsuite({'DemoTests'}); +xmlFile = 'BSPDemoTests.xml'; + +if nargin > 0 + xmlFile = [name,'_DemoTests.xml']; + suite = suite.selectIf('Name',['*',name,'*']); +end + + +try + runner = matlab.unittest.TestRunner.withTextOutput('OutputDetail',1); + runner.addPlugin(DiagnosticsValidationPlugin) + + xmlFile = 'BSPDemoTests.xml'; + plugin = XMLPlugin.producingJUnitFormat(xmlFile); + runner.addPlugin(plugin); + + results = runner.run(suite); + + t = table(results); + disp(t); + disp(repmat('#',1,80)); + for test = results + if test.Failed + disp(test.Name); + end + end +catch e + disp(getReport(e,'extended')); + bdclose('all'); + exit(1); +end + +save(['BSPInstallerTest_',datestr(now,'dd_mm_yyyy-HH:MM:SS'),'.mat'],'t'); +bdclose('all'); +exit(any([results.Failed])); diff --git a/test/runInstallerTests.m b/test/runInstallerTests.m new file mode 100755 index 0000000..14825fa --- /dev/null +++ b/test/runInstallerTests.m @@ -0,0 +1,48 @@ +function runInstallerTests(board) + +import matlab.unittest.TestRunner; +import matlab.unittest.TestSuite; +import matlab.unittest.plugins.TestReportPlugin; +import matlab.unittest.plugins.XMLPlugin +import matlab.unittest.plugins.DiagnosticsValidationPlugin +import matlab.unittest.parameters.Parameter + +SynthesizeDesign = {false}; +param = Parameter.fromData('SynthesizeDesign',SynthesizeDesign); + +if nargin == 0 + suite = testsuite({'BSPInstallerTests'}); +else + boards = ['*',lower(board),'*']; + suite = TestSuite.fromClass(?BSPInstallerTests,'ExternalParameters',param); + suite = suite.selectIf('ParameterProperty','configs', 'ParameterName',boards); +end + +try + + runner = matlab.unittest.TestRunner.withTextOutput('OutputDetail',1); + runner.addPlugin(DiagnosticsValidationPlugin) + + xmlFile = 'BSPTestResults.xml'; + plugin = XMLPlugin.producingJUnitFormat(xmlFile); + runner.addPlugin(plugin); + + results = runner.run(suite); + + t = table(results); + disp(t); + disp(repmat('#',1,80)); + for test = results + if test.Failed + disp(test.Name); + end + end +catch e + disp(getReport(e,'extended')); + bdclose('all'); + exit(1); +end + +save(['BSPInstallerTest_',datestr(now,'dd_mm_yyyy-HH:MM:SS'),'.mat'],'t'); +bdclose('all'); +exit(any([results.Failed])); diff --git a/test/runNonHWTest.m b/test/runNonHWTest.m new file mode 100755 index 0000000..c3561c1 --- /dev/null +++ b/test/runNonHWTest.m @@ -0,0 +1,39 @@ +function suite = runNonHWTest() + +import matlab.unittest.TestRunner; +import matlab.unittest.TestSuite; +import matlab.unittest.plugins.TestReportPlugin; +import matlab.unittest.plugins.XMLPlugin +import matlab.unittest.plugins.DiagnosticsValidationPlugin + +suite = testsuite({'NonHWTest'}); +xmlFile = 'BSPDemoTests.xml'; + + +try + runner = matlab.unittest.TestRunner.withTextOutput('OutputDetail',1); + runner.addPlugin(DiagnosticsValidationPlugin) + + xmlFile = 'BSPDemoTests.xml'; + plugin = XMLPlugin.producingJUnitFormat(xmlFile); + runner.addPlugin(plugin); + + results = runner.run(suite); + + t = table(results); + disp(t); + disp(repmat('#',1,80)); + for test = results + if test.Failed + disp(test.Name); + end + end +catch e + disp(getReport(e,'extended')); + bdclose('all'); + exit(1); +end + +save(['BSPInstallerTest_',datestr(now,'dd_mm_yyyy-HH:MM:SS'),'.mat'],'t'); +bdclose('all'); +exit(any([results.Failed])); diff --git a/test/runSynthTests.m b/test/runSynthTests.m new file mode 100644 index 0000000..e0fdc67 --- /dev/null +++ b/test/runSynthTests.m @@ -0,0 +1,68 @@ +function runSynthTests(board) + +import matlab.unittest.TestRunner; +import matlab.unittest.TestSuite; +import matlab.unittest.plugins.TestReportPlugin; +import matlab.unittest.plugins.XMLPlugin +import matlab.unittest.plugins.ToUniqueFile; +import matlab.unittest.plugins.TAPPlugin; +import matlab.unittest.plugins.DiagnosticsValidationPlugin +import matlab.unittest.parameters.Parameter + +runParallel = false; +SynthesizeDesign = {true}; +param = Parameter.fromData('SynthesizeDesign',SynthesizeDesign); + +if nargin == 0 + suite = testsuite({'BSPTests'}); +else + boards = ['*',lower(board),'*']; + suite = TestSuite.fromClass(?BSPTests,'ExternalParameters',param); + suite = suite.selectIf('ParameterProperty','configs', 'ParameterName',boards); +end + +try + + runner = matlab.unittest.TestRunner.withTextOutput('OutputDetail',4); + runner.addPlugin(DiagnosticsValidationPlugin) + + xmlFile = 'BSPTestResults.xml'; + plugin = XMLPlugin.producingJUnitFormat(xmlFile); + runner.addPlugin(plugin); + + if runParallel + try %#ok + parpool(4); + results = runInParallel(runner,suite); + catch ME + disp(ME); + results = runner.run(suite); + end + else + results = runner.run(suite); + end + + t = table(results); + disp(t); + disp(repmat('#',1,80)); + for test = results + if test.Failed + disp(test.Name); + end + end +catch e + disp(getReport(e,'extended')); + bdclose('all'); + exit(1); +end + +try + poolobj = gcp('nocreate'); + delete(poolobj); +catch ME + disp(ME) +end + +save(['BSPTest_',datestr(now,'dd_mm_yyyy-HH:MM:SS'),'.mat'],'t'); +bdclose('all'); +exit(any([results.Failed])); diff --git a/test/setportmapping.m b/test/setportmapping.m new file mode 100644 index 0000000..295644e --- /dev/null +++ b/test/setportmapping.m @@ -0,0 +1,106 @@ +function mdl = setportmapping(mode,ReferenceDesignName,board_name) + +% ! this script will work with test models that have 16 data ports and 4 +% boolean ports + +if contains(lower(ReferenceDesignName),'cn0585') + dev = 'CN0585'; + mdl = 'testModel'; + portWidthRX = 16; + portWidthTX = 16; +else + error('Unknown device'); +end + +load_system(mdl); + +% First set all ports to NIS +for k=1:16 + hdlset_param([mdl,'/HDL_DUT/in',num2str(k)], 'IOInterface', 'No Interface Specified'); + hdlset_param([mdl,'/HDL_DUT/in',num2str(k)], 'IOInterfaceMapping', ''); + hdlset_param([mdl,'/HDL_DUT/out',num2str(k)], 'IOInterface', 'No Interface Specified'); + hdlset_param([mdl,'/HDL_DUT/out',num2str(k)], 'IOInterfaceMapping', ''); +end + +for k = 1:4 + hdlset_param([mdl,'/HDL_DUT/validIn',num2str(k)], 'IOInterface', 'No Interface Specified'); + hdlset_param([mdl,'/HDL_DUT/validIn',num2str(k)], 'IOInterfaceMapping', ''); + hdlset_param([mdl,'/HDL_DUT/validOut',num2str(k)], 'IOInterface', 'No Interface Specified'); + hdlset_param([mdl,'/HDL_DUT/validOut',num2str(k)], 'IOInterfaceMapping', ''); +end + + +filePath = '../CI/ports.json'; +str = fileread(filePath); +val = jsondecode(str); + +fn = fieldnames(val); + +for k = 1:numel(fn) + x = val.(fn{k}); + if (strcmp(x.chip, dev)) + inIndex = 1; + outIndex = 1; + validInIndex = 1; + validOutIndex = 1; + if (mode == "rx") || (mode == "rxtx") + rx = x.ports.rx; + for indexRx = 1:numel(rx) + element = rx(indexRx); + if(element.type == "data") + if(element.input == "true") + hdlset_param([mdl,'/HDL_DUT/in',num2str(inIndex)], 'IOInterface', [element.m_name,' [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in',num2str(inIndex)], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + inIndex = inIndex + 1; + else + hdlset_param([mdl,'/HDL_DUT/out',num2str(outIndex)], 'IOInterface', [element.m_name,' [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out',num2str(outIndex)], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + outIndex = outIndex + 1; + end + elseif (element.type == "valid") + if(element.input == "true") + hdlset_param([mdl,'/HDL_DUT/validIn',num2str(validInIndex)], 'IOInterface', element.m_name); + hdlset_param([mdl,'/HDL_DUT/validIn',num2str(validInIndex)], 'IOInterfaceMapping', '[0]'); + validInIndex = validInIndex + 1; + else + hdlset_param([mdl,'/HDL_DUT/validOut',num2str(validOutIndex)], 'IOInterface', element.m_name); + hdlset_param([mdl,'/HDL_DUT/validOut',num2str(validOutIndex)], 'IOInterfaceMapping', '[0]'); + validOutIndex = validOutIndex + 1; + end + end + end + + end + if (mode == "tx") || (mode == "rxtx") + tx = x.ports.tx; + if (mode == "tx") + inIndex = 1; + outIndex = 1; + end + for indexTx = 1:numel(tx) + element = tx(indexTx); + if(element.type == "data") + if(element.input == "true") + hdlset_param([mdl,'/HDL_DUT/in',num2str(inIndex)], 'IOInterface', [element.m_name,' [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in',num2str(inIndex)], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + inIndex = inIndex + 1; + else + hdlset_param([mdl,'/HDL_DUT/out',num2str(outIndex)], 'IOInterface', [element.m_name,' [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out',num2str(outIndex)], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + outIndex = outIndex + 1; + end + elseif (element.type == "valid") + if(element.input == "true") + hdlset_param([mdl,'/HDL_DUT/validIn',num2str(validInIndex)], 'IOInterface', element.m_name); + hdlset_param([mdl,'/HDL_DUT/validIn',num2str(validInIndex)], 'IOInterfaceMapping', '[0]'); + validInIndex = validInIndex + 1; + else + hdlset_param([mdl,'/HDL_DUT/validOut',num2str(validOutIndex)], 'IOInterface', element.m_name); + hdlset_param([mdl,'/HDL_DUT/validOut',num2str(validOutIndex)], 'IOInterfaceMapping', '[0]'); + validOutIndex = validOutIndex + 1; + end + end + end + end + end +end diff --git a/test/testModel.slx b/test/testModel.slx new file mode 100755 index 0000000000000000000000000000000000000000..7021254b239104aff571777a8837041fd577d024 GIT binary patch literal 58678 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 literal 0 HcmV?d00001 From d621839ed1abb89e2c04efca5b5a5643060bf40b Mon Sep 17 00:00:00 2001 From: Stanca Pop Date: Tue, 11 Jul 2023 16:22:14 +0300 Subject: [PATCH 04/10] cn0585: Add AXI4 Lite R/WR Simulink test model --- ...cn0585_host_axi4_lite_read_write_example.slx | Bin 0 -> 27263 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 pcx_examples/streaming/cn0585_fmcz/cn0585_host_axi4_lite_read_write_example.slx diff --git a/pcx_examples/streaming/cn0585_fmcz/cn0585_host_axi4_lite_read_write_example.slx b/pcx_examples/streaming/cn0585_fmcz/cn0585_host_axi4_lite_read_write_example.slx new file mode 100755 index 0000000000000000000000000000000000000000..1b130f7c4aba982532de2a4786a68c97056ec17b GIT binary patch literal 27263 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 Date: Thu, 20 Jul 2023 14:05:11 +0300 Subject: [PATCH 05/10] Add cn0585 custom targeting --- .../CN0585_streaming_axi4lite_read_write.m | 0 ...0585_host_axi4_lite_read_write_example.slx | Bin .../zynq-zed-adv7511-cn0585.dts | 269 ++++++++++++++++++ .../+common/add_io.m | 17 ++ .../hdlcoder_ref_design_customization.m | 20 ++ .../+common/plugin_board.m | 29 ++ .../+common/plugin_rd.m | 110 +++++++ .../+zed/+tx/add_tx_io.m | 107 +++++++ .../+tx/hdlcoder_ref_design_customization.m | 20 ++ .../+zed/+tx/plugin_board.m | 9 + .../+zed/+tx/plugin_rd.m | 8 + .../hdlworkflow_cn0585_gpio_zed_tx.m | 38 +++ .../testModel_Tx16and8.slx | Bin 0 -> 45619 bytes .../cn0585_fmcz/cn0585_hdl/adi_build.tcl | 59 ++++ .../cn0585_fmcz/cn0585_hdl/build_bsp.sh | 88 ++++++ .../cn0585_fmcz/cn0585_hdl/fh_preprocess.tcl | 6 + .../cn0585_hdl/matlab_processors.tcl | 138 +++++++++ .../cn0585_fmcz/cn0585_hdl/ports.json | 176 ++++++++++++ .../cn0585_hdl/system_project_rxtx.tcl | 35 +++ .../testModel_Tx16and8.slx | Bin 0 -> 45619 bytes 20 files changed, 1129 insertions(+) rename pcx_examples/streaming/cn0585_fmcz/{ => cn0585_axi4_lite_rw_demo}/CN0585_streaming_axi4lite_read_write.m (100%) rename pcx_examples/streaming/cn0585_fmcz/{ => cn0585_axi4_lite_rw_demo}/cn0585_host_axi4_lite_read_write_example.slx (100%) create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m create mode 100644 pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx create mode 100644 pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/adi_build.tcl create mode 100755 pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/build_bsp.sh create mode 100644 pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/fh_preprocess.tcl create mode 100755 pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl create mode 100755 pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/ports.json create mode 100644 pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/system_project_rxtx.tcl create mode 100644 pcx_examples/targeting/cn0585_fmcz/cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx diff --git a/pcx_examples/streaming/cn0585_fmcz/CN0585_streaming_axi4lite_read_write.m b/pcx_examples/streaming/cn0585_fmcz/cn0585_axi4_lite_rw_demo/CN0585_streaming_axi4lite_read_write.m similarity index 100% rename from pcx_examples/streaming/cn0585_fmcz/CN0585_streaming_axi4lite_read_write.m rename to pcx_examples/streaming/cn0585_fmcz/cn0585_axi4_lite_rw_demo/CN0585_streaming_axi4lite_read_write.m diff --git a/pcx_examples/streaming/cn0585_fmcz/cn0585_host_axi4_lite_read_write_example.slx b/pcx_examples/streaming/cn0585_fmcz/cn0585_axi4_lite_rw_demo/cn0585_host_axi4_lite_read_write_example.slx similarity index 100% rename from pcx_examples/streaming/cn0585_fmcz/cn0585_host_axi4_lite_read_write_example.slx rename to pcx_examples/streaming/cn0585_fmcz/cn0585_axi4_lite_rw_demo/cn0585_host_axi4_lite_read_write_example.slx diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts new file mode 100644 index 0000000..d2260bb --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts @@ -0,0 +1,269 @@ +/dts-v1/; + +#include "zynq-zed.dtsi" +#include "zynq-zed-adv7511.dtsi" +#include +#include +#include + +/ { + clocks { + ext_clk: clock@0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <120000000>; + }; + }; + + one-bit-adc-dac@0 { + compatible = "adi,one-bit-adc-dac"; + #address-cells = <1>; + #size-cells = <0>; + + in-gpios = <&gpio_mux 4 GPIO_ACTIVE_HIGH>, + <&gpio_mux 5 GPIO_ACTIVE_HIGH>; + out-gpios = <&gpio_mux 3 GPIO_ACTIVE_HIGH>, + <&gpio_mux 2 GPIO_ACTIVE_HIGH>, + <&gpio_mux 1 GPIO_ACTIVE_HIGH>, + <&gpio_mux 0 GPIO_ACTIVE_HIGH>, + <&gpio_mux 6 GPIO_ACTIVE_HIGH>, + <&gpio_mux 7 GPIO_ACTIVE_HIGH>, + <&gpio_mux 11 GPIO_ACTIVE_HIGH>, + <&gpio_mux 12 GPIO_ACTIVE_HIGH>, + <&gpio_mux 13 GPIO_ACTIVE_HIGH>, + <&gpio_mux 14 GPIO_ACTIVE_HIGH>; + + channel@0 { + reg = <0>; + label = "GPIO4_VIO"; + }; + channel@1 { + reg = <1>; + label = "GPIO5_VIO"; + }; + channel@2 { + reg = <2>; + label = "GPIO0_VIO"; + }; + channel@3 { + reg = <3>; + label = "GPIO1_VIO"; + }; + channel@4 { + reg = <4>; + label = "GPIO2_VIO"; + }; + channel@5 { + reg = <5>; + label = "GPIO3_VIO"; + }; + channel@6 { + reg = <6>; + label = "GPIO6_VIO"; + }; + channel@7 { + reg = <7>; + label = "GPIO7_VIO"; + }; + channel@8 { + reg = <8>; + label = "PAD_ADC0"; + }; + channel@9 { + reg = <9>; + label = "PAD_ADC1"; + }; + channel@10 { + reg = <10>; + label = "PAD_ADC2"; + }; + channel@11 { + reg = <11>; + label = "PAD_ADC3"; + }; + }; +}; + +&fpga_axi { + axi_pwm_gen: pwm@44B10000 { + compatible = "adi,axi-pwmgen"; + reg = <0x44B10000 0x1000>; + label = "ltc2387_if"; + #pwm-cells = <2>; + clocks = <&ext_clk>; + }; + + ref_clk: clk@44B00000 { + compatible = "adi,axi-clkgen-2.00.a"; + reg = <0x44B00000 0x10000>; + #clock-cells = <0>; + clocks = <&clkc 15>, <&clkc 15>; + clock-names = "s_axi_aclk", "clkin1"; + clock-output-names = "ref_clk"; + }; + + rx_dma: dmac@44A40000 { + compatible = "adi,axi-dmac-1.00.a"; + reg = <0x44A40000 0x1000>; + #dma-cells = <1>; + interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc 15>; + + adi,channels { + #size-cells = <0>; + #address-cells = <1>; + + dma-channel@0 { + reg = <0>; + adi,source-bus-width = <64>; + adi,source-bus-type = <2>; + adi,destination-bus-width = <64>; + adi,destination-bus-type = <0>; + }; + }; + }; + + ltc2387@0{ + compatible = "ltc2387-16-x4"; + pwms = <&axi_pwm_gen 0 0 + &axi_pwm_gen 1 0>; + pwm-names = "cnv", "clk_en"; + clocks = <&ref_clk>; + dmas = <&rx_dma 0>; + dma-names = "rx"; + adi,use-two-lanes; + }; + + qspi0: spi@0x44B20000 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44B20000 0x1000>; + num-cs = <0x2>; + compatible = "xlnx,xps-spi-2.00.a"; + bits-per-word = <16>; + fifo-size = <16>; + clock-names = "ext_spi_clk", "s_axi_aclk"; + clocks = <&clkc 15>, <&clkc 15>; + interrupt-names = "ip2intc_irpt"; + interrupt-parent = <&intc>; + interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>; + + gpio_mux: max7301@0 { + compatible = "max7301"; + reg = <0>; + spi-max-frequency = <20000000>; + #gpio-cells = <2>; + gpio-controller; + }; + }; + + dac0_tx_dma: tx-dmac@0x44D30000 { + compatible = "adi,axi-dmac-1.00.a"; + reg = <0x44D30000 0x10000>; + #dma-cells = <1>; + interrupt-parent = <&intc>; + interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc 15>; + + adi,channels { + #size-cells = <0>; + #address-cells = <1>; + + dma-channel@0 { + reg = <0>; + adi,source-bus-width = <32>; + adi,source-bus-type = <0>; + adi,destination-bus-width = <32>; + adi,destination-bus-type = <1>; + }; + }; + }; + + dac1_tx_dma: tx-dmac@0x44E30000 { + compatible = "adi,axi-dmac-1.00.a"; + reg = <0x44E30000 0x10000>; + #dma-cells = <1>; + interrupt-parent = <&intc>; + interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc 15>; + + adi,channels { + #size-cells = <0>; + #address-cells = <1>; + + dma-channel@0 { + reg = <0>; + adi,source-bus-width = <32>; + adi,source-bus-type = <0>; + adi,destination-bus-width = <32>; + adi,destination-bus-type = <1>; + }; + }; + }; + + axi_ad3552r_0: axi-ad3552r-0@44d04000 { + compatible = "adi,axi-ad3552r"; + reg = <0x44d04000 0x1000>; + + reset-gpios = <&gpio0 90 GPIO_ACTIVE_LOW>; + + clocks = <&ref_clk>; + + dmas = <&dac0_tx_dma 0>; + dma-names = "tx"; + }; + + axi_ad3552r_1: axi-ad3552r-1@44e04000 { + compatible = "adi,axi-ad3552r"; + reg = <0x44e04000 0x1000>; + + clocks = <&ref_clk>; + + dmas = <&dac1_tx_dma 0>; + dma-names = "tx"; + }; + + mwipcore@43c00000 { + compatible = "mathworks,mwipcore-v3.00"; + reg = <0x43C00000 0xfffff>; + #address-cells = <1>; + #size-cells = <0>; + mmwr-channel@0{ + reg = <0x0>; + compatible = "mathworks,mm-write-channel-v1.00"; + }; + mmrd-channel@1{ + reg = <0x1>; + compatible = "mathworks,mm-read-channel-v1.00"; + }; + + + }; + + i2c@41620000 { + compatible = "xlnx,axi-iic-1.01.b", "xlnx,xps-iic-2.00.a"; + reg = <0x41620000 0x10000>; + interrupt-parent = <&intc>; + interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc 15>; + clock-names = "pclk"; + + #size-cells = <0>; + #address-cells = <1>; + + eeprom@50 { + compatible = "at24,24c02"; + reg = <0x50>; + }; + eeprom2@54 { + compatible = "at24,24c02"; + reg = <0x54>; + }; + ad7291_1@20 { + label = "ADC_I2C_1"; + compatible = "adi,ad7291"; + reg = <0x20>; + }; + + }; +}; diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m new file mode 100644 index 0000000..6cd8cdc --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m @@ -0,0 +1,17 @@ +% function add_io(hRD,project,fpga,type) +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % Add AXI4 and AXI4-Lite slave interfaces +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% out = AnalogDevices.get_memory_axi_interface_info(fpga,lower(project)); +% hRD.addAXI4SlaveInterface( ... +% 'InterfaceConnection', out.InterfaceConnection, ... +% 'BaseAddress', out.BaseAddress, ... +% 'MasterAddressSpace', out.MasterAddressSpace); +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % Add Reference design interfaces +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% AnalogDevices.add_io_ports(hRD,lower(project),lower(type),lower(fpga)); +% +% end diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m new file mode 100644 index 0000000..31e4cea --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m @@ -0,0 +1,20 @@ +function [rd,boardName] = hdlcoder_ref_design_customization +% Reference design plugin registration file +% 1. The registration file with this name inside of a board plugin folder +% will be picked up +% 2. Any registration file with this name on MATLAB path will also be picked up +% 3. The registration file returns a cell array pointing to the location of +% the reference design plugins +% 4. The registration file also returns its associated board name +% 5. Reference design plugin must be a package folder accessible from +% MATLAB path, and contains a reference design definition file + +% Copyright 2013-2014 The MathWorks, Inc. + +rd = {... + 'AnalogDevicesDemo.cn0585_led_sw_gpio_control_demo.zed.tx.plugin_rd', ... + }; + +boardName = 'AnalogDevices CN0585 GPIO Control'; + +end diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m new file mode 100644 index 0000000..27d0b67 --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m @@ -0,0 +1,29 @@ +function hB = plugin_board(BoardName) +% Use Plugin API to create board plugin object + +% Copyright 2015 The MathWorks, Inc. + +hB = hdlcoder.Board; + +% Target Board Information +hB.BoardName = sprintf('AnalogDevices CN0585 GPIO Control'); + +% FPGA Device +hB.FPGAVendor = 'Xilinx'; +hB.FPGAFamily = 'Zynq'; + +% Determine the device based on the board + +hB.FPGADevice = sprintf('xc7%s', 'z020'); +hB.FPGAPackage = 'clg484'; +hB.FPGASpeed = '-1'; +hB.FPGAFamily = 'Zynq'; + +% Tool Info +hB.SupportedTool = {'Xilinx Vivado'}; + +% FPGA JTAG chain position +hB.JTAGChainPosition = 2; + +%% Add interfaces +% Standard "External Port" interface diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m new file mode 100644 index 0000000..5bc799a --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m @@ -0,0 +1,110 @@ +function hRD = plugin_rd(board, design) +% Reference design definition + +% Copyright 2014-2015 The MathWorks, Inc. + +% pname = upper(project); +% ppath = project; +% if strcmpi(project, 'cn0585') +% ppath = 'cn0585_fmcz'; +% end + +board = 'zed'; +design = 'Tx'; + +hRD = hdlcoder.ReferenceDesign('SynthesisTool', 'Xilinx Vivado'); + +% This is the base reference design that other RDs can build upon +hRD.ReferenceDesignName = sprintf('%s (%s)', upper(board), design); + +% Determine the board name based on the design +hRD.BoardName = sprintf('AnalogDevices CN0585 GPIO Control'); + +% Tool information +hRD.SupportedToolVersion = {'2022.2'}; + +% Get the root directories +rootDirExample = fileparts(strtok(mfilename('fullpath'), '+')); +tmp = strsplit(rootDirExample,filesep); + +if isunix + rootDir = fullfile(filesep,tmp{1:end-3}); +else + rootDir = fullfile(tmp{1:end-3}); +end +rootDirBSP = fullfile('hdl','vendor','AnalogDevices','vivado'); + +% Design files are shared +hRD.SharedRD = true; +hRD.SharedRDFolder = rootDir; + +%% Set top level project pieces +hRD.addParameter( ... + 'ParameterID', 'project', ... + 'DisplayName', 'HDL Project Subfolder', ... + 'DefaultValue', 'cn0585_fmcz'); + +hRD.addParameter( ... + 'ParameterID', 'carrier', ... + 'DisplayName', 'HDL Project Carrier', ... + 'DefaultValue', 'zed'); + +%% Add custom design files +hRD.addCustomVivadoDesign( ... + 'CustomBlockDesignTcl', fullfile('pcx_examples', 'targeting', 'cn0585_fmcz', 'cn0585_hdl', 'system_project_rxtx.tcl')); + +%% Standard reference design pieces +hRD.BlockDesignName = 'system'; + +% custom source files +hRD.CustomFiles = {... + fullfile('projects')..., + fullfile('library')..., + fullfile('scripts')..., + }; + +% custom source files +hRD.CustomFiles = {... + fullfile(rootDirBSP, 'scripts')..., + fullfile(rootDirBSP, 'library')..., + fullfile(rootDirBSP, 'library','xilinx')..., + fullfile(rootDirBSP, 'projects','common')..., + fullfile(rootDirBSP, 'projects','scripts')..., + fullfile(rootDirBSP, 'projects','cn0585_fmcz')..., + fullfile(rootDirBSP, 'projects','cn0585_fmcz', 'common')..., + fullfile(rootDirBSP, 'projects','cn0585_fmcz', 'zed')..., + fullfile('pcx_examples', 'targeting', 'cn0585_fmcz', 'cn0585_hdl')..., + }; + +hRD.addParameter( ... + 'ParameterID', 'ref_design', ... + 'DisplayName', 'Reference Type', ... + 'DefaultValue', lower(strrep(design, ' & ',''))); + +hRD.addParameter( ... + 'ParameterID', 'fpga_board', ... + 'DisplayName', 'FPGA Boad', ... + 'DefaultValue', upper(board)); + +hRD.addParameter( ... + 'ParameterID', 'preprocess', ... + 'DisplayName', 'Preprocess', ... + 'DefaultValue', 'on'); +hRD.addParameter( ... + 'ParameterID', 'preprocess_script', ... + 'DisplayName', 'Preprocess Script', ... + 'DefaultValue', fullfile('pcx_examples', 'targeting', 'cn0585_fmcz','cn0585_hdl','fh_preprocess.tcl')); + +hRD.addParameter( ... + 'ParameterID', 'postprocess', ... + 'DisplayName', 'Postprocess', ... + 'DefaultValue', 'off'); + +%% Add IO +%AnalogDevices.add_io(hRD,'cn0585_led_sw_gpio_control_demo',board,design); + +%% Add interfaces +% add clock interface +hRD.addClockInterface( ... + 'ClockConnection', 'axi_clkgen/clk_0', ... + 'ResetConnection', 'sampling_clk_rstgen/peripheral_aresetn'); diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m new file mode 100644 index 0000000..a5c9ae0 --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m @@ -0,0 +1,107 @@ +function add_tx_io(hRD) + +% add AXI4 and AXI4-Lite slave interfaces +hRD.addAXI4SlaveInterface( ... + 'InterfaceConnection', 'axi_cpu_interconnect/M20_AXI', ... + 'BaseAddress', '0x43C00000', ... + 'MasterAddressSpace', 'sys_ps7/Data'); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Tx Reference design interfaces +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data 0 IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'axi_ltc2387_0_adc_data', ... + 'PortWidth', 16, ... + 'InterfaceConnection', 'axi_ltc2387_0/adc_data', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data 1 IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'axi_ltc2387_1_adc_data', ... + 'PortWidth', 16, ... + 'InterfaceConnection', 'axi_ltc2387_1/adc_data', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data 2 IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'axi_ltc2387_2_adc_data', ... + 'PortWidth', 16, ... + 'InterfaceConnection', 'axi_ltc2387_2/adc_data', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data 3 IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'axi_ltc2387_3_adc_data', ... + 'PortWidth', 16, ... + 'InterfaceConnection', 'axi_ltc2387_3/adc_data', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Load Tx Data OUT', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_ad3552r_0_valid_in_a', ... + 'PortWidth', 1, ... + 'InterfaceConnection', 'axi_ad3552r_0/valid_in_a', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Valid Tx Data IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'axi_ltc2387_0_adc_valid', ... + 'PortWidth', 1, ... + 'InterfaceConnection', 'axi_ltc2387_0/adc_valid', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'CN0585 DAC Data 0 OUT', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_ad3552r_0_data_in_a', ... + 'PortWidth', 16, ... + 'InterfaceConnection', 'axi_ad3552r_0/data_in_a', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'CN0585 DAC Data 1 OUT', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_ad3552r_0_data_in_b', ... + 'PortWidth', 16, ... + 'InterfaceConnection', 'axi_ad3552r_0/data_in_b', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'CN0585 DAC Data 2 OUT', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_ad3552r_1_data_in_a', ... + 'PortWidth', 16, ... + 'InterfaceConnection', 'axi_ad3552r_1/data_in_a', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'CN0585 DAC Data 3 OUT', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_ad3552r_1_data_in_b', ... + 'PortWidth', 16, ... + 'InterfaceConnection', 'axi_ad3552r_1/data_in_b', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'GPIO IN SW', ... + 'InterfaceType', 'IN', ... + 'PortName', 'xlslice_1_Dout', ... + 'PortWidth', 8, ... + 'InterfaceConnection', 'xlslice_1/Dout', ... + 'IsRequired', false); + +hRD.addInternalIOInterface( ... + 'InterfaceID', 'GPIO OUT LED', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'xlconcat_1_In1', ... + 'PortWidth', 8, ... + 'InterfaceConnection', 'xlconcat_1/In1', ... + 'IsRequired', false); diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m new file mode 100644 index 0000000..350b2b3 --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m @@ -0,0 +1,20 @@ +function [rd, boardName] = hdlcoder_ref_design_customization +% Reference design plugin registration file +% 1. The registration file with this name inside of a board plugin folder +% will be picked up +% 2. Any registration file with this name on MATLAB path will also be picked up +% 3. The registration file returns a cell array pointing to the location of +% the reference design plugins +% 4. The registration file also returns its associated board name +% 5. Reference design plugin must be a package folder accessible from +% MATLAB path, and contains a reference design definition file + +% Copyright 2013-2014 The MathWorks, Inc. + +rd = {... + 'AnalogDevicesDemo.cn0585_led_sw_gpio_control_demo.zed.tx.plugin_rd', ... + }; + +boardName = 'AnalogDevicesDemo cn0585_led_sw_gpio_control AnalogDevies CN0585 GPIO Control (Tx)'; + +end diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m new file mode 100644 index 0000000..8e69678 --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m @@ -0,0 +1,9 @@ +function hP = plugin_board() +% Zynq Platform PCore +% Use Plugin API to create board plugin object + +% Copyright 2015 The MathWorks, Inc. + +% Call the common board definition function +% hP = AnalogDevicesDemo.cn0585_led_sw_gpio_control_demo.common.plugin_board('AnalogDevies CN0585 GPIO Control ', 'Tx'); +hP = AnalogDevicesDemo.cn0585_led_sw_gpio_control_demo.common.plugin_board('AnalogDevies CN0585 GPIO Control'); \ No newline at end of file diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m new file mode 100644 index 0000000..f381dcf --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m @@ -0,0 +1,8 @@ +function hRD = plugin_rd +% Reference design definition + +% Copyright 2014-2015 The MathWorks, Inc. + +% Call the common reference design definition function +hRD = AnalogDevicesDemo.cn0585_led_sw_gpio_control_demo.common.plugin_rd('AnalogDevies CN0585 GPIO Control', 'Tx'); +AnalogDevicesDemo.cn0585_led_sw_gpio_control_demo.zed.tx.add_tx_io(hRD); diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m new file mode 100644 index 0000000..bd9e518 --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m @@ -0,0 +1,38 @@ +function out = hdlworkflow_cn0585_gpio_zed_tx(vivado) + +if nargin < 1 + vivado = '2022.2'; +end + +%-------------------------------------------------------------------------- +% HDL Workflow Script +% Generated with MATLAB 9.8 (R2020a) at 12:56:00 on 24/09/2020 +% This script was generated using the following parameter values: +% Filename : '/tmp/hsx-add-boot-bin-test/test/hdlworkflow_daq2_zcu102_rx.m' +% Overwrite : true +% Comments : true +% Headers : true +% DUT : 'testModel_Rx64Tx64/HDL_DUT' +% To view changes after modifying the workflow, run the following command: +% >> hWC.export('DUT','testModel_Rx64Tx64/HDL_DUT'); +%-------------------------------------------------------------------------- + +%% Load the Model +load_system('testModel_Tx16and8'); + +%% Restore the Model to default HDL parameters +hdlrestoreparams('testModel_Tx16and8/HDL_DUT'); + +%% Model HDL Parameters +%% Set Model 'testModel_Rx64Tx64' HDL parameters +hdlset_param('testModel_Tx16and8', 'HDLSubsystem', 'testModel_Tx16and8/HDL_DUT'); +hdlset_param('testModel_Tx16and8', 'ReferenceDesign', 'AnalogDevies CN0585 GPIO Control (TX)'); +hdlset_param('testModel_Tx16and8', 'SynthesisTool', 'Xilinx Vivado'); +hdlset_param('testModel_Tx16and8', 'SynthesisToolChipFamily', 'Zynq'); +hdlset_param('testModel_Tx16and8', 'SynthesisToolDeviceName', 'xc7z020-clg484-1'); +hdlset_param('testModel_Tx16and8', 'SynthesisToolPackageName', ''); +hdlset_param('testModel_Tx16and8', 'SynthesisToolSpeedValue', ''); +hdlset_param('testModel_Tx16and8', 'TargetDirectory', 'hdl_prj/hdlsrc'); +hdlset_param('testModel_Tx16and8', 'TargetLanguage', 'Verilog'); +hdlset_param('testModel_Tx16and8', 'TargetPlatform', 'AnalogDevices CN0585 GPIO Control'); +hdlset_param('testModel_Tx16and8', 'Workflow', 'IP Core Generation'); diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx new file mode 100644 index 0000000000000000000000000000000000000000..55d8cf32b77baf85b87b10565df283c148ff25e9 GIT binary patch literal 45619 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 RA_;5&9@OioQ})-|{{zK|@Z ../../../../hdl/vendor/AnalogDevices/vivado/library/axi_ad9361/axi_ad9361_delay.tcl diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/fh_preprocess.tcl b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/fh_preprocess.tcl new file mode 100644 index 0000000..38d8bcb --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/fh_preprocess.tcl @@ -0,0 +1,6 @@ +set ad_hdl_dir [pwd] + +#### Move files +file rename -force $ad_hdl_dir/hdl/vendor/AnalogDevices/vivado/scripts $ad_hdl_dir/scripts +file rename -force $ad_hdl_dir/hdl/vendor/AnalogDevices/vivado/projects $ad_hdl_dir/projects +file rename -force $ad_hdl_dir/hdl/vendor/AnalogDevices/vivado/library $ad_hdl_dir/library diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl new file mode 100755 index 0000000..5376448 --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl @@ -0,0 +1,138 @@ +proc preprocess_bd {project carrier rxtx} { + + puts "Preprocessing $project $carrier $rxtx" + + switch $project { + cn0585_fmcz { + # Disconnect the ADC PACK pins + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] + + set sys_cstring "matlab $rxtx" + sysid_gen_sys_init_file $sys_cstring + + # Disconnect adc_valid + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_valid] + # Reconnect the adc_valid in the system + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins axi_ltc2387_dma/fifo_wr_en] + + if {$rxtx == "rx"} { + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins axi_ad3552r_0/data_in_a] + connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins axi_ad3552r_0/data_in_b] + connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins axi_ad3552r_1/data_in_a] + connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins axi_ad3552r_1/data_in_b] + } + + if {$rxtx == "tx"} { + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_0] + connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_1] + connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_2] + connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_3] + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_en] + } + + if {$rxtx == "tx" || $rxtx == "rxtx"} { + + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_valid] + + # Connect dac valids together + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_0/valid_in_b] + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_a] + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_b] + + # Remove the gpio bd connections + delete_bd_objs [get_bd_nets gpio_i_1] + delete_bd_objs [get_bd_nets sys_ps7_GPIO_O] + # Split the input gpios into 3 to separate the switches + create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_0 + set_property -dict [list \ + CONFIG.DIN_FROM {63} \ + CONFIG.DIN_TO {19} \ + CONFIG.DIN_WIDTH {64} \ + CONFIG.DOUT_WIDTH {45} \ + ] [get_bd_cells xlslice_0] + create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_1 + set_property -dict [list \ + CONFIG.DIN_FROM {18} \ + CONFIG.DIN_TO {11} \ + CONFIG.DIN_WIDTH {64} \ + CONFIG.DOUT_WIDTH {8} \ + ] [get_bd_cells xlslice_1] + create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_2 + set_property -dict [list \ + CONFIG.DIN_FROM {10} \ + CONFIG.DIN_TO {0} \ + CONFIG.DIN_WIDTH {64} \ + CONFIG.DOUT_WIDTH {11} \ + ] [get_bd_cells xlslice_2] + # Reconnect the input gpios + connect_bd_net [get_bd_ports gpio_i] [get_bd_pins xlslice_0/Din] + connect_bd_net [get_bd_ports gpio_i] [get_bd_pins xlslice_1/Din] + connect_bd_net [get_bd_ports gpio_i] [get_bd_pins xlslice_2/Din] + create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_0 + set_property CONFIG.NUM_PORTS {3} [get_bd_cells xlconcat_0] + set_property -dict [list CONFIG.IN2_WIDTH.VALUE_SRC USER CONFIG.IN1_WIDTH.VALUE_SRC USER CONFIG.IN0_WIDTH.VALUE_SRC USER] [get_bd_cells xlconcat_0] + set_property -dict [list \ + CONFIG.IN0_WIDTH {45} \ + CONFIG.IN1_WIDTH {8} \ + CONFIG.IN2_WIDTH {11} \ + ] [get_bd_cells xlconcat_0] + connect_bd_net [get_bd_pins xlslice_0/Dout] [get_bd_pins xlconcat_0/In0] + connect_bd_net [get_bd_pins xlslice_2/Dout] [get_bd_pins xlconcat_0/In2] + # Reconnect the input gpios to the ps7 + connect_bd_net [get_bd_pins sys_ps7/GPIO_I] [get_bd_pins xlconcat_0/dout] + # Split the output gpios into 3 to separate the leds + create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_3 + set_property -dict [list \ + CONFIG.DIN_FROM {63} \ + CONFIG.DIN_TO {27} \ + CONFIG.DIN_WIDTH {64} \ + CONFIG.DOUT_WIDTH {37} \ + ] [get_bd_cells xlslice_3] + create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_4 + set_property -dict [list \ + CONFIG.DIN_FROM {26} \ + CONFIG.DIN_TO {19} \ + CONFIG.DIN_WIDTH {64} \ + CONFIG.DOUT_WIDTH {8} \ + ] [get_bd_cells xlslice_4] + create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_5 + set_property -dict [list \ + CONFIG.DIN_FROM {18} \ + CONFIG.DIN_TO {0} \ + CONFIG.DIN_WIDTH {64} \ + CONFIG.DOUT_WIDTH {19} \ + ] [get_bd_cells xlslice_5] + # Reconnect the output gpios + connect_bd_net [get_bd_pins sys_ps7/GPIO_O] [get_bd_pins xlslice_3/Din] + connect_bd_net [get_bd_pins sys_ps7/GPIO_O] [get_bd_pins xlslice_4/Din] + connect_bd_net [get_bd_pins sys_ps7/GPIO_O] [get_bd_pins xlslice_5/Din] + create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_1 + set_property CONFIG.NUM_PORTS {3} [get_bd_cells xlconcat_1] + set_property -dict [list CONFIG.IN2_WIDTH.VALUE_SRC USER CONFIG.IN1_WIDTH.VALUE_SRC USER CONFIG.IN0_WIDTH.VALUE_SRC USER] [get_bd_cells xlconcat_1] + set_property -dict [list \ + CONFIG.IN0_WIDTH {37} \ + CONFIG.IN1_WIDTH {8} \ + CONFIG.IN2_WIDTH {19} \ + ] [get_bd_cells xlconcat_1] + connect_bd_net [get_bd_pins xlslice_3/Dout] [get_bd_pins xlconcat_1/In0] + connect_bd_net [get_bd_pins xlslice_5/Dout] [get_bd_pins xlconcat_1/In2] + # Reconnect the output gpios to the output port + connect_bd_net [get_bd_ports gpio_o] [get_bd_pins xlconcat_1/Dout] + + } + switch $carrier { + zed { + set_property -dict [list CONFIG.NUM_MI {21}] [get_bd_cells axi_cpu_interconnect] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ACLK] [get_bd_pins axi_clkgen/clk_0] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ARESETN] [get_bd_pins sampling_clk_rstgen/peripheral_aresetn] + } + } + } + } +} diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/ports.json b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/ports.json new file mode 100755 index 0000000..f972fc3 --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/ports.json @@ -0,0 +1,176 @@ +{ + "cn0585": { + "chip": "CN0585", + "complex": "true", + "fpga": [ + "zed" + ], + "supported_rd": [ + "rx", + "tx", + "rx & tx" + ], + "ports": [ + { + "rx": [ + { + "input": "false", + "width": 1, + "name": "util_ltc2387_adc_pack/fifo_wr_en", + "type": "valid", + "m_name": "IP Data Valid OUT" + }, + { + "input": "false", + "width": 16, + "name": "util_ltc2387_adc_pack/fifo_wr_data_0", + "type": "data", + "m_name": "IP Data 0 OUT" + }, + { + "input": "false", + "width": 16, + "name": "util_ltc2387_adc_pack/fifo_wr_data_1", + "type": "data", + "m_name": "IP Data 1 OUT" + }, + { + "input": "false", + "width": 16, + "name": "util_ltc2387_adc_pack/fifo_wr_data_2", + "type": "data", + "m_name": "IP Data 2 OUT" + }, + { + "input": "false", + "width": 16, + "name": "util_ltc2387_adc_pack/fifo_wr_data_3", + "type": "data", + "m_name": "IP Data 3 OUT" + }, + { + "input": "true", + "width": 1, + "name": "axi_ltc2387_0/adc_valid", + "type": "valid", + "m_name": "IP Valid Rx Data IN" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_0/adc_data", + "type": "data", + "m_name": "CN0585 ADC Data 0 IN" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_1/adc_data", + "type": "data", + "m_name": "CN0585 ADC Data 1 IN" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_2/adc_data", + "type": "data", + "m_name": "CN0585 ADC Data 2 IN" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_3/adc_data", + "type": "data", + "m_name": "CN0585 ADC Data 3 IN" + } + ], + "tx": [ + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_0/adc_data", + "type": "data", + "m_name": "IP Data 0 IN" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_1/adc_data", + "type": "data", + "m_name": "IP Data 1 IN" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_2/adc_data", + "type": "data", + "m_name": "IP Data 2 IN" + }, + { + "input": "true", + "width": 16, + "name": "axi_ltc2387_3/adc_data", + "type": "data", + "m_name": "IP Data 3 IN" + }, + { + "input": "true", + "width": 1, + "name": "axi_ltc2387_0/adc_valid", + "type": "valid", + "m_name": "IP Valid Tx Data IN" + }, + { + "input": "false", + "width": 16, + "name": "axi_ad3552r_0/data_in_a", + "type": "data", + "m_name": "CN0585 DAC Data 0 OUT" + }, + { + "input": "false", + "width": 16, + "name": "axi_ad3552r_0/data_in_b", + "type": "data", + "m_name": "CN0585 DAC Data 1 OUT" + }, + { + "input": "false", + "width": 1, + "name": "axi_ad3552r_0/valid_in_a", + "type": "valid", + "m_name": "IP Load Tx Data OUT" + }, + { + "input": "false", + "width": 16, + "name": "axi_ad3552r_1/data_in_a", + "type": "data", + "m_name": "CN0585 DAC Data 2 OUT" + }, + { + "input": "false", + "width": 16, + "name": "axi_ad3552r_1/data_in_b", + "type": "data", + "m_name": "CN0585 DAC Data 3 OUT" + }, + { + "input": "true", + "width": 8, + "name": "xlslice_1/Dout", + "type": "data", + "m_name": "IP Data 4 IN" + }, + { + "input": "false", + "width": 8, + "name": "xlconcat_1/In1", + "type": "data", + "m_name": "CN0585 DAC Data 4 OUT" + } + ] + } + ] + } +} diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/system_project_rxtx.tcl b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/system_project_rxtx.tcl new file mode 100644 index 0000000..d180513 --- /dev/null +++ b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/system_project_rxtx.tcl @@ -0,0 +1,35 @@ +set start_dir [pwd] +puts "Starting Precision Toolbox HDL build" + +if {$preprocess == "on"} { + source $preprocess_script +} + +cd projects/$project/$carrier +source ../../scripts/adi_make.tcl +adi_make::lib all + +set ::env(ADI_SKIP_SYNTHESIS) 1 +set ::env(SKIP_SYNTHESIS) 1 +set ::env(ADI_MATLAB) 1 +set ::env(MATLAB) 1 +set ::env(ADI_USE_OOC_SYNTHESYS) 1 +set ::env(ADI_IGNORE_VERSION_CHECK) 1 + +source ./system_project.tcl + +# Update block design to make room for new IP +source ../../scripts/matlab_processors.tcl +preprocess_bd $project $carrier $ref_design + +if {$postprocess == "on"} { + cd $start_dir + source $postprocess_script +} + +regenerate_bd_layout +save_bd_design +validate_bd_design + +# Back to root +cd $start_dir diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx b/pcx_examples/targeting/cn0585_fmcz/cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx new file mode 100644 index 0000000000000000000000000000000000000000..55d8cf32b77baf85b87b10565df283c148ff25e9 GIT binary patch literal 45619 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 RA_;5&9@OioQ})-|{{zK|@Z Date: Thu, 26 Oct 2023 10:59:36 +0300 Subject: [PATCH 06/10] cn0585: Add doc support --- CI/doc/SysObjsProps.m | 1 + CI/doc/genhtml.m | 2 +- CI/gen_doc/docs/assets/rd_cn0585.svg | 293 ++++++++++++++++++++++++++ CI/gen_doc/docs/gen_hdl_refdesigns.py | 2 + CI/gen_doc/docs/gen_rd_svg.py | 4 +- CI/gen_doc/docs/gen_sysobj_doc.m | 5 +- 6 files changed, 303 insertions(+), 4 deletions(-) create mode 100644 CI/gen_doc/docs/assets/rd_cn0585.svg diff --git a/CI/doc/SysObjsProps.m b/CI/doc/SysObjsProps.m index c088b24..6983493 100644 --- a/CI/doc/SysObjsProps.m +++ b/CI/doc/SysObjsProps.m @@ -9,3 +9,4 @@ % * AD7768 % * AD2S1210 % * AD4020 +% * CN0585 and diff --git a/CI/doc/genhtml.m b/CI/doc/genhtml.m index 77043be..cad2ec3 100644 --- a/CI/doc/genhtml.m +++ b/CI/doc/genhtml.m @@ -1,6 +1,6 @@ mfiledir = '..\..\+adi\'; docdir = '..\..\doc\'; -parts = {'AD4630','AD4030','AD463x','AD7768','AD4858','AD2S1210','AD4020'}; +parts = {'AD4630','AD4030','AD463x','AD7768','AD4858','AD2S1210','AD4020','CN0585'}; trx_files = {'Rx','Base','Tx'}; for ii = 1:numel(parts) for jj = 1:numel(trx_files) diff --git a/CI/gen_doc/docs/assets/rd_cn0585.svg b/CI/gen_doc/docs/assets/rd_cn0585.svg new file mode 100644 index 0000000..b00ccdb --- /dev/null +++ b/CI/gen_doc/docs/assets/rd_cn0585.svg @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CI/gen_doc/docs/gen_hdl_refdesigns.py b/CI/gen_doc/docs/gen_hdl_refdesigns.py index 74f8c07..45e991b 100644 --- a/CI/gen_doc/docs/gen_hdl_refdesigns.py +++ b/CI/gen_doc/docs/gen_hdl_refdesigns.py @@ -32,6 +32,8 @@ def update_hdl_refdesigns(): objs[obj]["rd_image"] = "ad9361" elif objs[obj]["name"] in ["adrv9002"]: objs[obj]["rd_image"] = "adrv9001" + elif objs[obj]["name"] in ["cn0585"]: + objs[obj]["rd_image"] = "cn0585" else: objs[obj]["rd_image"] = "jesd" diff --git a/CI/gen_doc/docs/gen_rd_svg.py b/CI/gen_doc/docs/gen_rd_svg.py index 8cb6f6b..3c833be 100644 --- a/CI/gen_doc/docs/gen_rd_svg.py +++ b/CI/gen_doc/docs/gen_rd_svg.py @@ -1,7 +1,7 @@ import os def gen_rd_svg(): - refs = ["rd_ad9361","rd_adrv9001","rd_jesd"] + refs = ["rd_ad9361","rd_adrv9001","rd_cn0585","rd_jesd"] css_out = "" for ref in refs: @@ -10,8 +10,10 @@ def gen_rd_svg(): svg = f.read() selectable_boxes = { + "AXIAD3552RBox": {"link": "https://wiki.analog.com/resources/fpga/docs/axi_ad3552r"}, "AXIAD9361Box": {"link": "https://wiki.analog.com/resources/fpga/docs/axi_ad9361"}, "AXIADRV9002Box": {"link": "https://wiki.analog.com/resources/eval/user-guides/adrv9002/axi_adrv9002"}, + "AXILTC2387Box": {"link": "https://wiki.analog.com/resources/fpga/docs/axi_ltc2387"}, "TxDMAEngineBox": {"link": "https://wiki.analog.com/resources/fpga/docs/axi_dmac"}, "TxUPACKBox": {"link": "https://wiki.analog.com/resources/fpga/docs/util_upack"}, "TxFIFOBox": {"link": "https://wiki.analog.com/resources/fpga/docs/util_rfifo"}, diff --git a/CI/gen_doc/docs/gen_sysobj_doc.m b/CI/gen_doc/docs/gen_sysobj_doc.m index f4e0c29..1256284 100644 --- a/CI/gen_doc/docs/gen_sysobj_doc.m +++ b/CI/gen_doc/docs/gen_sysobj_doc.m @@ -16,6 +16,7 @@ , {'AD4858', {'Rx'}}... , {'AD2S1210', {'Rx'}}... , {'AD4020', {'Rx'}}... + , {'CN0585', {'Rx','Tx'}}... %{'QuadMxFE',{'Rx','Tx'}}... }; @@ -24,9 +25,9 @@ for jj = 1:numel(rootClasses{ii}{2}) part = rootClasses{ii}{1}; tmp = rootClasses{ii}{2}; - trx_file = tmp{jj}; + pcx_file = tmp{jj}; all_props = []; - dotmfilename = strcat(mfiledir, '.', part, '.', trx_file); + dotmfilename = strcat(mfiledir, '.', part, '.', pcx_file); props = unique(properties(dotmfilename)); for prop = 1:length(props) From 1a2b920f0790f89965d6dee9a70188a7bd5a92c7 Mon Sep 17 00:00:00 2001 From: Stanca Pop Date: Thu, 26 Oct 2023 11:03:29 +0300 Subject: [PATCH 07/10] doc: Add requirements_doc.txt --- CI/gen_doc/requirements_doc.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 CI/gen_doc/requirements_doc.txt diff --git a/CI/gen_doc/requirements_doc.txt b/CI/gen_doc/requirements_doc.txt new file mode 100644 index 0000000..060c0f8 --- /dev/null +++ b/CI/gen_doc/requirements_doc.txt @@ -0,0 +1,6 @@ +numpy +mkdocs<1.5 +mkdocs-material +mkdocs-awesome-pages-plugin +mkdocs-mermaid2-plugin +mkdocs-plugin-inline-svg From 3bdac4bb64005f38ee768df6388e5415598b032f Mon Sep 17 00:00:00 2001 From: Stanca Pop Date: Thu, 2 Nov 2023 10:53:31 +0200 Subject: [PATCH 08/10] test: Remove unwanted files --- test/DemoTests.m | 74 --------------------------------------------- test/NonHWTest.m | 28 ----------------- test/runDemoTests.m | 44 --------------------------- test/runNonHWTest.m | 39 ------------------------ 4 files changed, 185 deletions(-) delete mode 100755 test/DemoTests.m delete mode 100755 test/NonHWTest.m delete mode 100755 test/runDemoTests.m delete mode 100755 test/runNonHWTest.m diff --git a/test/DemoTests.m b/test/DemoTests.m deleted file mode 100755 index a2f7d88..0000000 --- a/test/DemoTests.m +++ /dev/null @@ -1,74 +0,0 @@ -classdef DemoTests < matlab.uitest.TestCase - - properties - root = ''; - end - - methods(TestClassSetup) - function addpaths(testCase) - here = mfilename('fullpath'); - here = strsplit(here,'/'); - here = fullfile('/',here{1:end-2}); - testCase.root = here; - addpath(genpath(fullfile(here,'hdl'))); - end - function setupVivado(~) - v=ver('matlab'); Release = v.Release; - switch Release - case '(R2017a)' - vivado = '2016.2'; - case '(R2017b)' - vivado = '2017.4'; - case '(R2018b)' - vivado = '2017.4'; - case '(R2019a)' - vivado = '2018.2'; - case '(R2019b)' - vivado = '2018.2'; - case '(R2020a)' - vivado = '2018.2'; - case '(R2020b)' - vivado = '2018.2'; - case '(R2021a)' - vivado = '2018.2'; - case '(R2021b)' - vivado = '2021.1'; - case '(R2022a)' - vivado = '2022.2'; - end - if ispc - hdlsetuptoolpath('ToolName', 'Xilinx Vivado', ... - 'ToolPath', ['C:\Xilinx\Vivado\',vivado,'\bin\vivado.bat']); - elseif isunix - hdlsetuptoolpath('ToolName', 'Xilinx Vivado', ... - 'ToolPath', ['/opt/Xilinx/Vivado/',vivado,'/bin/vivado']); - end - - end - end - - methods(TestMethodTeardown) - function cleanup_hdl_prj(testCase) - dir = fullfile(testCase.root,'test','hdl_prj'); - if exist(dir, 'dir') - rmdir(fullfile(testCase.root,'test','hdl_prj'), 's'); - end - end - end - - methods(Test) - %function buildHDLDAQ2ZCU102_BOOTBIN(testCase) - % cd(fullfile(testCase.root,'test')); - % out = hdlworkflow_daq2_zcu102_rx('2018.2'); - % if ~isempty(out) - % disp(out.message); - % end - % % Check for BOOT.BIN - % if exist('hdl_prj/vivado_ip_prj/boot/BOOT.BIN', 'file') ~= 2 - % error('BOOT.BIN Failed'); - % end - %end - end - -end - diff --git a/test/NonHWTest.m b/test/NonHWTest.m deleted file mode 100755 index 4e04fc9..0000000 --- a/test/NonHWTest.m +++ /dev/null @@ -1,28 +0,0 @@ -classdef NonHWTest < matlab.unittest.TestCase - - properties(TestParameter) - rootClasses = {... - {'AD9081',{'Rx','Tx'}},... - {'AD9144',{'Tx'}},... - {'AD9152',{'Tx'}},... - {'AD9467',{'Rx'}},... - {'AD9680',{'Rx'}},... - {'DAQ2',{'Rx','Tx'}},... - {'QuadMxFE',{'Rx','Tx'}}... - }; - end - - methods (Test) - - function call_constructors(testCase,rootClasses) - for trx = rootClasses{2} - sdr = eval(['adi.',rootClasses{1},'.',trx{:},'()']); - testCase.assertEqual(class(sdr),['adi.',rootClasses{1},'.',trx{:}]); - end - end - - end - - -end - diff --git a/test/runDemoTests.m b/test/runDemoTests.m deleted file mode 100755 index e93f62d..0000000 --- a/test/runDemoTests.m +++ /dev/null @@ -1,44 +0,0 @@ -function suite = runDemoTests(name) - -import matlab.unittest.TestRunner; -import matlab.unittest.TestSuite; -import matlab.unittest.plugins.TestReportPlugin; -import matlab.unittest.plugins.XMLPlugin -import matlab.unittest.plugins.DiagnosticsValidationPlugin - -suite = testsuite({'DemoTests'}); -xmlFile = 'BSPDemoTests.xml'; - -if nargin > 0 - xmlFile = [name,'_DemoTests.xml']; - suite = suite.selectIf('Name',['*',name,'*']); -end - - -try - runner = matlab.unittest.TestRunner.withTextOutput('OutputDetail',1); - runner.addPlugin(DiagnosticsValidationPlugin) - - xmlFile = 'BSPDemoTests.xml'; - plugin = XMLPlugin.producingJUnitFormat(xmlFile); - runner.addPlugin(plugin); - - results = runner.run(suite); - - t = table(results); - disp(t); - disp(repmat('#',1,80)); - for test = results - if test.Failed - disp(test.Name); - end - end -catch e - disp(getReport(e,'extended')); - bdclose('all'); - exit(1); -end - -save(['BSPInstallerTest_',datestr(now,'dd_mm_yyyy-HH:MM:SS'),'.mat'],'t'); -bdclose('all'); -exit(any([results.Failed])); diff --git a/test/runNonHWTest.m b/test/runNonHWTest.m deleted file mode 100755 index c3561c1..0000000 --- a/test/runNonHWTest.m +++ /dev/null @@ -1,39 +0,0 @@ -function suite = runNonHWTest() - -import matlab.unittest.TestRunner; -import matlab.unittest.TestSuite; -import matlab.unittest.plugins.TestReportPlugin; -import matlab.unittest.plugins.XMLPlugin -import matlab.unittest.plugins.DiagnosticsValidationPlugin - -suite = testsuite({'NonHWTest'}); -xmlFile = 'BSPDemoTests.xml'; - - -try - runner = matlab.unittest.TestRunner.withTextOutput('OutputDetail',1); - runner.addPlugin(DiagnosticsValidationPlugin) - - xmlFile = 'BSPDemoTests.xml'; - plugin = XMLPlugin.producingJUnitFormat(xmlFile); - runner.addPlugin(plugin); - - results = runner.run(suite); - - t = table(results); - disp(t); - disp(repmat('#',1,80)); - for test = results - if test.Failed - disp(test.Name); - end - end -catch e - disp(getReport(e,'extended')); - bdclose('all'); - exit(1); -end - -save(['BSPInstallerTest_',datestr(now,'dd_mm_yyyy-HH:MM:SS'),'.mat'],'t'); -bdclose('all'); -exit(any([results.Failed])); From 191b36ec0b3aaea280353d07f17e7273456cd9da Mon Sep 17 00:00:00 2001 From: Stanca Pop Date: Thu, 18 Jul 2024 15:33:35 +0300 Subject: [PATCH 09/10] cn0585: Rename cn0585_fmcz to cn0585 --- .../+zed/hdlcoder_ref_design_customization.m | 6 +- .../hdlcoder_board_customization.m | 2 +- .../projects/scripts/matlab_processors.tcl | 58 +++++++++++++++++++ .../+common/plugin_rd.m | 18 +++--- .../cn0585_hdl/matlab_processors.tcl | 8 +-- test/board_variants.m | 6 +- 6 files changed, 78 insertions(+), 20 deletions(-) create mode 100755 hdl/vendor/AnalogDevices/vivado/projects/scripts/matlab_processors.tcl diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m index 8e2c2c9..a7b638c 100755 --- a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m @@ -12,9 +12,9 @@ % Copyright 2013-2014 The MathWorks, Inc. rd = {... - 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_rx', ... - 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_tx', ... - 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_rxtx', ... + 'AnalogDevices.cn0585.zed.plugin_rd_rx', ... + 'AnalogDevices.cn0585.zed.plugin_rd_tx', ... + 'AnalogDevices.cn0585.zed.plugin_rd_rxtx', ... }; boardName = 'AnalogDevices CN0585 ZED'; diff --git a/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m b/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m index d553377..a83f72a 100755 --- a/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m +++ b/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m @@ -9,7 +9,7 @@ % Copyright 2012-2013 The MathWorks, Inc. r = { ... - 'AnalogDevices.cn0585_fmcz.zed.plugin_board' ..., + 'AnalogDevices.cn0585.zed.plugin_board' ..., }; end % LocalWords: Zynq ZC diff --git a/hdl/vendor/AnalogDevices/vivado/projects/scripts/matlab_processors.tcl b/hdl/vendor/AnalogDevices/vivado/projects/scripts/matlab_processors.tcl new file mode 100755 index 0000000..093650d --- /dev/null +++ b/hdl/vendor/AnalogDevices/vivado/projects/scripts/matlab_processors.tcl @@ -0,0 +1,58 @@ +proc preprocess_bd {project carrier rxtx} { + + puts "Preprocessing $project $carrier $rxtx" + + switch $project { + cn0585 { + # Disconnect the ADC PACK pins + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] + + + set sys_cstring "matlab $rxtx" + sysid_gen_sys_init_file $sys_cstring + + #Disconnect adc_valid + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_valid] + # Reconnect the adc_valid in the system + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins axi_ltc2387_dma/fifo_wr_en] + + if {$rxtx == "rx"} { + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins axi_ad3552r_0/data_in_a] + connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins axi_ad3552r_0/data_in_b] + connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins axi_ad3552r_1/data_in_a] + connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins axi_ad3552r_1/data_in_b] + } + + if {$rxtx == "tx"} { + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_0] + connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_1] + connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_2] + connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_3] + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_en] + } + + if {$rxtx == "tx" || $rxtx == "rxtx"} { + + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_valid] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_valid] + + # Connect dac valids together + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_0/valid_in_b] + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_a] + connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_b] + } + switch $carrier { + zed { + set_property -dict [list CONFIG.NUM_MI {21}] [get_bd_cells axi_cpu_interconnect] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ACLK] [get_bd_pins axi_clkgen/clk_0] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ARESETN] [get_bd_pins sampling_clk_rstgen/peripheral_aresetn] + } + } + } + } +} diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m index 5bc799a..d277e32 100644 --- a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m +++ b/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m @@ -6,7 +6,7 @@ % pname = upper(project); % ppath = project; % if strcmpi(project, 'cn0585') -% ppath = 'cn0585_fmcz'; +% ppath = 'cn0585'; % end board = 'zed'; @@ -21,7 +21,7 @@ hRD.BoardName = sprintf('AnalogDevices CN0585 GPIO Control'); % Tool information -hRD.SupportedToolVersion = {'2022.2'}; +hRD.SupportedToolVersion = {'2023.2'}; % Get the root directories rootDirExample = fileparts(strtok(mfilename('fullpath'), '+')); @@ -42,7 +42,7 @@ hRD.addParameter( ... 'ParameterID', 'project', ... 'DisplayName', 'HDL Project Subfolder', ... - 'DefaultValue', 'cn0585_fmcz'); + 'DefaultValue', 'cn0585'); hRD.addParameter( ... 'ParameterID', 'carrier', ... @@ -51,7 +51,7 @@ %% Add custom design files hRD.addCustomVivadoDesign( ... - 'CustomBlockDesignTcl', fullfile('pcx_examples', 'targeting', 'cn0585_fmcz', 'cn0585_hdl', 'system_project_rxtx.tcl')); + 'CustomBlockDesignTcl', fullfile('pcx_examples', 'targeting', 'cn0585', 'cn0585_hdl', 'system_project_rxtx.tcl')); %% Standard reference design pieces hRD.BlockDesignName = 'system'; @@ -70,10 +70,10 @@ fullfile(rootDirBSP, 'library','xilinx')..., fullfile(rootDirBSP, 'projects','common')..., fullfile(rootDirBSP, 'projects','scripts')..., - fullfile(rootDirBSP, 'projects','cn0585_fmcz')..., - fullfile(rootDirBSP, 'projects','cn0585_fmcz', 'common')..., - fullfile(rootDirBSP, 'projects','cn0585_fmcz', 'zed')..., - fullfile('pcx_examples', 'targeting', 'cn0585_fmcz', 'cn0585_hdl')..., + fullfile(rootDirBSP, 'projects','cn0585')..., + fullfile(rootDirBSP, 'projects','cn0585', 'common')..., + fullfile(rootDirBSP, 'projects','cn0585', 'zed')..., + fullfile('pcx_examples', 'targeting', 'cn0585', 'cn0585_hdl')..., }; hRD.addParameter( ... @@ -93,7 +93,7 @@ hRD.addParameter( ... 'ParameterID', 'preprocess_script', ... 'DisplayName', 'Preprocess Script', ... - 'DefaultValue', fullfile('pcx_examples', 'targeting', 'cn0585_fmcz','cn0585_hdl','fh_preprocess.tcl')); + 'DefaultValue', fullfile('pcx_examples', 'targeting', 'cn0585','cn0585_hdl','fh_preprocess.tcl')); hRD.addParameter( ... 'ParameterID', 'postprocess', ... diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl index 5376448..ece7ad2 100755 --- a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl +++ b/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl @@ -3,12 +3,12 @@ proc preprocess_bd {project carrier rxtx} { puts "Preprocessing $project $carrier $rxtx" switch $project { - cn0585_fmcz { + cn0585 { # Disconnect the ADC PACK pins delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] set sys_cstring "matlab $rxtx" sysid_gen_sys_init_file $sys_cstring diff --git a/test/board_variants.m b/test/board_variants.m index 441c4ab..dc6e70c 100755 --- a/test/board_variants.m +++ b/test/board_variants.m @@ -9,9 +9,9 @@ % Copyright 2023 The MathWorks, Inc. r = { ... - 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_rx', ... - 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_tx', ... - 'AnalogDevices.cn0585_fmcz.zed.plugin_rd_rxtx', ... + 'AnalogDevices.cn0585.zed.plugin_rd_rx', ... + 'AnalogDevices.cn0585.zed.plugin_rd_tx', ... + 'AnalogDevices.cn0585.zed.plugin_rd_rxtx', ... }; end % LocalWords: Zynq ZC From 74d31035f2e089ea08bafb1e4cdb5b30afd8e4e5 Mon Sep 17 00:00:00 2001 From: Stanca Pop Date: Thu, 18 Jul 2024 16:29:23 +0300 Subject: [PATCH 10/10] cn0585: Remove/rename _fmcz folders --- CI/scripts_hdl/matlab_processors.tcl | 33 +++++++++--------- .../+zed/hdlcoder_ref_design_customization.m | 0 .../+zed/plugin_board.m | 0 .../+zed/plugin_rd_rx.m | 0 .../+zed/plugin_rd_rxtx.m | 0 .../+zed/plugin_rd_tx.m | 0 .../AnalogDevices/+AnalogDevices/plugin_rd.m | 2 +- .../projects/scripts/matlab_processors.tcl | 31 ++++++++-------- .../CN0585_streaming.m | 0 .../CN0585_streaming_axi4lite_read_write.m | 0 ...0585_host_axi4_lite_read_write_example.slx | Bin .../zynq-zed-adv7511-cn0585.dts | 0 .../+common/add_io.m | 0 .../hdlcoder_ref_design_customization.m | 0 .../+common/plugin_board.m | 0 .../+common/plugin_rd.m | 0 .../+zed/+tx/add_tx_io.m | 0 .../+tx/hdlcoder_ref_design_customization.m | 0 .../+zed/+tx/plugin_board.m | 0 .../+zed/+tx/plugin_rd.m | 0 .../hdlworkflow_cn0585_gpio_zed_tx.m | 0 .../testModel_Tx16and8.slx | Bin .../cn0585_hdl/adi_build.tcl | 0 .../cn0585_hdl/build_bsp.sh | 2 +- .../cn0585_hdl/fh_preprocess.tcl | 0 .../cn0585_hdl/matlab_processors.tcl | 0 .../cn0585_hdl/ports.json | 0 .../cn0585_hdl/system_project_rxtx.tcl | 0 .../testModel_Tx16and8.slx | Bin test/BSPTestsBase.m | 32 +++++++++++++---- test/build_design.m | 2 +- 31 files changed, 60 insertions(+), 42 deletions(-) rename hdl/vendor/AnalogDevices/+AnalogDevices/{+cn0585_fmcz => +cn0585}/+zed/hdlcoder_ref_design_customization.m (100%) rename hdl/vendor/AnalogDevices/+AnalogDevices/{+cn0585_fmcz => +cn0585}/+zed/plugin_board.m (100%) rename hdl/vendor/AnalogDevices/+AnalogDevices/{+cn0585_fmcz => +cn0585}/+zed/plugin_rd_rx.m (100%) rename hdl/vendor/AnalogDevices/+AnalogDevices/{+cn0585_fmcz => +cn0585}/+zed/plugin_rd_rxtx.m (100%) rename hdl/vendor/AnalogDevices/+AnalogDevices/{+cn0585_fmcz => +cn0585}/+zed/plugin_rd_tx.m (100%) rename pcx_examples/streaming/{cn0585_fmcz => cn0585}/CN0585_streaming.m (100%) rename pcx_examples/streaming/{cn0585_fmcz => cn0585}/cn0585_axi4_lite_rw_demo/CN0585_streaming_axi4lite_read_write.m (100%) rename pcx_examples/streaming/{cn0585_fmcz => cn0585}/cn0585_axi4_lite_rw_demo/cn0585_host_axi4_lite_read_write_example.slx (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/cn0585_hdl/adi_build.tcl (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/cn0585_hdl/build_bsp.sh (99%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/cn0585_hdl/fh_preprocess.tcl (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/cn0585_hdl/matlab_processors.tcl (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/cn0585_hdl/ports.json (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/cn0585_hdl/system_project_rxtx.tcl (100%) rename pcx_examples/targeting/{cn0585_fmcz => cn0585}/cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx (100%) diff --git a/CI/scripts_hdl/matlab_processors.tcl b/CI/scripts_hdl/matlab_processors.tcl index 12427a1..dc47d1f 100755 --- a/CI/scripts_hdl/matlab_processors.tcl +++ b/CI/scripts_hdl/matlab_processors.tcl @@ -3,13 +3,12 @@ proc preprocess_bd {project carrier rxtx} { puts "Preprocessing $project $carrier $rxtx" switch $project { - cn0585_fmcz { + cn0585 { # Disconnect the ADC PACK pins - delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] - + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] set sys_cstring "matlab $rxtx" sysid_gen_sys_init_file $sys_cstring @@ -20,21 +19,21 @@ proc preprocess_bd {project carrier rxtx} { connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins axi_ltc2387_dma/fifo_wr_en] if {$rxtx == "rx"} { - connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins axi_ad3552r_0/data_in_a] + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins axi_ad3552r_0/data_in_a] connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins axi_ad3552r_0/data_in_b] connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins axi_ad3552r_1/data_in_a] connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins axi_ad3552r_1/data_in_b] } if {$rxtx == "tx"} { - connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_0] + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_0] connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_1] connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_2] connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_3] connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_en] } - if {$rxtx == "tx" || $rxtx == "rxtx"} { + if {$rxtx == "tx" || $rxtx == "rxtx"} { delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_valid] delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_valid] @@ -45,14 +44,14 @@ proc preprocess_bd {project carrier rxtx} { connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_0/valid_in_b] connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_a] connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_b] - } - switch $carrier { - zed { - set_property -dict [list CONFIG.NUM_MI {21}] [get_bd_cells axi_cpu_interconnect] - connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ACLK] [get_bd_pins axi_clkgen/clk_0] - connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ARESETN] [get_bd_pins sampling_clk_rstgen/peripheral_aresetn] - } - } + } + switch $carrier { + zed { + set_property -dict [list CONFIG.NUM_MI {21}] [get_bd_cells axi_cpu_interconnect] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ACLK] [get_bd_pins axi_clkgen/clk_0] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ARESETN] [get_bd_pins sampling_clk_rstgen/peripheral_aresetn] + } + } } } } diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/hdlcoder_ref_design_customization.m similarity index 100% rename from hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/hdlcoder_ref_design_customization.m rename to hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/hdlcoder_ref_design_customization.m diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_board.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/plugin_board.m similarity index 100% rename from hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_board.m rename to hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/plugin_board.m diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/plugin_rd_rx.m similarity index 100% rename from hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rx.m rename to hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/plugin_rd_rx.m diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rxtx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/plugin_rd_rxtx.m similarity index 100% rename from hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_rxtx.m rename to hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/plugin_rd_rxtx.m diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_tx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/plugin_rd_tx.m similarity index 100% rename from hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585_fmcz/+zed/plugin_rd_tx.m rename to hdl/vendor/AnalogDevices/+AnalogDevices/+cn0585/+zed/plugin_rd_tx.m diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_rd.m b/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_rd.m index 3ae31d6..b7736a5 100755 --- a/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_rd.m +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/plugin_rd.m @@ -6,7 +6,7 @@ pname = upper(project); ppath = project; if strcmpi(project, 'cn0585') - ppath = 'cn0585_fmcz'; + ppath = 'cn0585'; end % Construct reference design object diff --git a/hdl/vendor/AnalogDevices/vivado/projects/scripts/matlab_processors.tcl b/hdl/vendor/AnalogDevices/vivado/projects/scripts/matlab_processors.tcl index 093650d..dc47d1f 100755 --- a/hdl/vendor/AnalogDevices/vivado/projects/scripts/matlab_processors.tcl +++ b/hdl/vendor/AnalogDevices/vivado/projects/scripts/matlab_processors.tcl @@ -5,11 +5,10 @@ proc preprocess_bd {project carrier rxtx} { switch $project { cn0585 { # Disconnect the ADC PACK pins - delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] - delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] - + delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_2_adc_data] + delete_bd_objs [get_bd_nets axi_ltc2387_3_adc_data] set sys_cstring "matlab $rxtx" sysid_gen_sys_init_file $sys_cstring @@ -20,21 +19,21 @@ proc preprocess_bd {project carrier rxtx} { connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins axi_ltc2387_dma/fifo_wr_en] if {$rxtx == "rx"} { - connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins axi_ad3552r_0/data_in_a] + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins axi_ad3552r_0/data_in_a] connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins axi_ad3552r_0/data_in_b] connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins axi_ad3552r_1/data_in_a] connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins axi_ad3552r_1/data_in_b] } if {$rxtx == "tx"} { - connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_0] + connect_bd_net [get_bd_pins axi_ltc2387_0/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_0] connect_bd_net [get_bd_pins axi_ltc2387_1/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_1] connect_bd_net [get_bd_pins axi_ltc2387_2/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_2] connect_bd_net [get_bd_pins axi_ltc2387_3/adc_data] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_data_3] connect_bd_net [get_bd_pins axi_ltc2387_0/adc_valid] [get_bd_pins util_ltc2387_adc_pack/fifo_wr_en] } - if {$rxtx == "tx" || $rxtx == "rxtx"} { + if {$rxtx == "tx" || $rxtx == "rxtx"} { delete_bd_objs [get_bd_nets axi_ltc2387_0_adc_valid] delete_bd_objs [get_bd_nets axi_ltc2387_1_adc_valid] @@ -45,14 +44,14 @@ proc preprocess_bd {project carrier rxtx} { connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_0/valid_in_b] connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_a] connect_bd_net [get_bd_pins axi_ad3552r_0/valid_in_a] [get_bd_pins axi_ad3552r_1/valid_in_b] - } - switch $carrier { - zed { - set_property -dict [list CONFIG.NUM_MI {21}] [get_bd_cells axi_cpu_interconnect] - connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ACLK] [get_bd_pins axi_clkgen/clk_0] - connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ARESETN] [get_bd_pins sampling_clk_rstgen/peripheral_aresetn] - } - } + } + switch $carrier { + zed { + set_property -dict [list CONFIG.NUM_MI {21}] [get_bd_cells axi_cpu_interconnect] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ACLK] [get_bd_pins axi_clkgen/clk_0] + connect_bd_net [get_bd_pins axi_cpu_interconnect/M20_ARESETN] [get_bd_pins sampling_clk_rstgen/peripheral_aresetn] + } + } } } } diff --git a/pcx_examples/streaming/cn0585_fmcz/CN0585_streaming.m b/pcx_examples/streaming/cn0585/CN0585_streaming.m similarity index 100% rename from pcx_examples/streaming/cn0585_fmcz/CN0585_streaming.m rename to pcx_examples/streaming/cn0585/CN0585_streaming.m diff --git a/pcx_examples/streaming/cn0585_fmcz/cn0585_axi4_lite_rw_demo/CN0585_streaming_axi4lite_read_write.m b/pcx_examples/streaming/cn0585/cn0585_axi4_lite_rw_demo/CN0585_streaming_axi4lite_read_write.m similarity index 100% rename from pcx_examples/streaming/cn0585_fmcz/cn0585_axi4_lite_rw_demo/CN0585_streaming_axi4lite_read_write.m rename to pcx_examples/streaming/cn0585/cn0585_axi4_lite_rw_demo/CN0585_streaming_axi4lite_read_write.m diff --git a/pcx_examples/streaming/cn0585_fmcz/cn0585_axi4_lite_rw_demo/cn0585_host_axi4_lite_read_write_example.slx b/pcx_examples/streaming/cn0585/cn0585_axi4_lite_rw_demo/cn0585_host_axi4_lite_read_write_example.slx similarity index 100% rename from pcx_examples/streaming/cn0585_fmcz/cn0585_axi4_lite_rw_demo/cn0585_host_axi4_lite_read_write_example.slx rename to pcx_examples/streaming/cn0585/cn0585_axi4_lite_rw_demo/cn0585_host_axi4_lite_read_write_example.slx diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_axi4_lite_demo/zynq-zed-adv7511-cn0585.dts diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/add_io.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/hdlcoder_ref_design_customization.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_board.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+common/plugin_rd.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/add_tx_io.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/hdlcoder_ref_design_customization.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_board.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/+zed/+tx/plugin_rd.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/hdlworkflow_cn0585_gpio_zed_tx.m diff --git a/pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx b/pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx rename to pcx_examples/targeting/cn0585/+AnalogDevicesDemo/+cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/adi_build.tcl b/pcx_examples/targeting/cn0585/cn0585_hdl/adi_build.tcl similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/adi_build.tcl rename to pcx_examples/targeting/cn0585/cn0585_hdl/adi_build.tcl diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/build_bsp.sh b/pcx_examples/targeting/cn0585/cn0585_hdl/build_bsp.sh similarity index 99% rename from pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/build_bsp.sh rename to pcx_examples/targeting/cn0585/cn0585_hdl/build_bsp.sh index 1591df1..d8ec41d 100755 --- a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/build_bsp.sh +++ b/pcx_examples/targeting/cn0585/cn0585_hdl/build_bsp.sh @@ -2,7 +2,7 @@ set -x cd "$(dirname "$0")" if [ -z "${HDLBRANCH}" ]; then -HDLBRANCH='cn0585_pr' +HDLBRANCH='main' fi # Script is designed to run from specific location diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/fh_preprocess.tcl b/pcx_examples/targeting/cn0585/cn0585_hdl/fh_preprocess.tcl similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/fh_preprocess.tcl rename to pcx_examples/targeting/cn0585/cn0585_hdl/fh_preprocess.tcl diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl b/pcx_examples/targeting/cn0585/cn0585_hdl/matlab_processors.tcl similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/matlab_processors.tcl rename to pcx_examples/targeting/cn0585/cn0585_hdl/matlab_processors.tcl diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/ports.json b/pcx_examples/targeting/cn0585/cn0585_hdl/ports.json similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/ports.json rename to pcx_examples/targeting/cn0585/cn0585_hdl/ports.json diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/system_project_rxtx.tcl b/pcx_examples/targeting/cn0585/cn0585_hdl/system_project_rxtx.tcl similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/cn0585_hdl/system_project_rxtx.tcl rename to pcx_examples/targeting/cn0585/cn0585_hdl/system_project_rxtx.tcl diff --git a/pcx_examples/targeting/cn0585_fmcz/cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx b/pcx_examples/targeting/cn0585/cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx similarity index 100% rename from pcx_examples/targeting/cn0585_fmcz/cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx rename to pcx_examples/targeting/cn0585/cn0585_led_sw_gpio_control_demo/testModel_Tx16and8.slx diff --git a/test/BSPTestsBase.m b/test/BSPTestsBase.m index 09b5c6c..6e4f37f 100644 --- a/test/BSPTestsBase.m +++ b/test/BSPTestsBase.m @@ -66,6 +66,11 @@ function CollectLogs(testCase,cfgb) disp('Found workflow_task_CreateProject... copying'); movefile('workflow_task_CreateProject.log',[rdn,'_CreateProject_',cfgb.mode,'.log']); end + system(join(["find '",testCase.Folder,"' -name 'system_top_timing_summary_routed.rpt' | xargs -I '{}' cp {} ."],'')); + if exist('system_top_timing_summary_routed.rpt','file') + disp('Found system_top_timing_summary_routed... copying'); + movefile('system_top_timing_summary_routed.rpt',[rdn,'_timing_summary_',cfgb.mode,'.rpt']); + end system(join(["find '",testCase.Folder,"' -name 'workflow_task_BuildFPGABitstream.log' | xargs -I '{}' cp {} ."],'')); if exist('workflow_task_BuildFPGABitstream.log','file') disp('Found workflow_task_BuildFPGABitstream... copying'); @@ -109,6 +114,15 @@ function CollectLogs(testCase,cfgb) 'vivado_version',vivado_version,'mode',mode); cfg = [cfg(:)',{cfg1},{cfg2},{cfg3}]; + mode = 'tx_rx'; + h2 = str2func([s,'.',variants{k},'.plugin_rd_txrx']);h2 = h2(); + ReferenceDesignName = h2.ReferenceDesignName; + vivado_version = h2.SupportedToolVersion{:}; + cfg4 = struct('Board',h1,... + 'ReferenceDesignName',ReferenceDesignName,... + 'vivado_version',vivado_version,'mode',mode); + cfg = [cfg(:)',{cfg1},{cfg2},{cfg4}]; + end end @@ -124,7 +138,7 @@ function CollectLogs(testCase,cfgb) assert(0); elseif strcmp(s{2},'adrv9361z7035') || ... strcmp(s{2},'adrv9364z7020') - h = str2func([strjoin(s(1:2),'.'),'.common.plugin_board']); + h = str2func([strjoin(s(1:2),'.'),'.plugin_board']); else h = str2func([strjoin(s(1:end-1),'.'),'.plugin_board']); end @@ -138,10 +152,16 @@ function CollectLogs(testCase,cfgb) end function setVivadoPath(~,vivado) - if ispc - pathname = ['C:\Xilinx\Vivado\',vivado,'\bin\vivado.bat']; - elseif isunix - pathname = ['/opt/Xilinx/Vivado/',vivado,'/bin/vivado']; + CUSTOM_VIVADO_PATH = getenv('CUSTOM_VIVADO_PATH'); + if ~isempty(CUSTOM_VIVADO_PATH) + pathname = CUSTOM_VIVADO_PATH; + fprintf('Using custom Vivado path: %s\n',pathname); + else + if ispc + pathname = ['C:\Xilinx\Vivado\',vivado,'\bin\vivado.bat']; + elseif isunix + pathname = ['/emea/mediadata/opt/Xilinx/Vivado/',vivado,'/bin/vivado']; + end end assert(exist(pathname,'file')>0,'Correct version of Vivado is unavailable or in a non-standard location'); hdlsetuptoolpath('ToolName', 'Xilinx Vivado', ... @@ -183,4 +203,4 @@ function testMain(testCase, configs, SynthesizeDesign) end end end -end +end \ No newline at end of file diff --git a/test/build_design.m b/test/build_design.m index 8930f65..b14c71b 100755 --- a/test/build_design.m +++ b/test/build_design.m @@ -29,7 +29,7 @@ % Specify the top level project directory hWC.ProjectFolder = folder; -hWC.ReferenceDesignToolVersion = vivado_version; +hWC.ReferenceDesignToolVersion = '2023.2'; hWC.IgnoreToolVersionMismatch = true; hWC.AllowUnsupportedToolVersion = true;