diff --git a/+adi/+AD9144/Base.m b/+adi/+AD9144/Base.m new file mode 100644 index 00000000..f897be4f --- /dev/null +++ b/+adi/+AD9144/Base.m @@ -0,0 +1,75 @@ +classdef (Abstract) Base < matlabshared.libiio.base & ... + matlab.system.mixin.CustomIcon + %AD9144 Base Summary of this class goes here + % Detailed explanation goes here + + 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 = 'int16'; + 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(['AD9144 ',obj.Type]); + end + + 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 = 'AD9144'; + end + + end +end + diff --git a/+adi/+AD9144/Tx.m b/+adi/+AD9144/Tx.m new file mode 100644 index 00000000..0cb4585e --- /dev/null +++ b/+adi/+AD9144/Tx.m @@ -0,0 +1,60 @@ +classdef Tx < adi.AD9144.Base & adi.common.Tx & adi.common.DDS + % adi.AD9144.Tx Transmit data to the AD9144 high speed DAC + % The adi.AD9144.Tx System object is a signal source that can send + % complex data from the AD9144. + % + % tx = adi.AD9144.Tx; + % tx = adi.AD9144.Tx('uri','192.168.2.1'); + % + % AD9144 Datasheet + % + % See also adi.DAQ2.Tx + + properties (Constant) + %SamplingRate Sampling Rate + % Baseband sampling rate in Hz, specified as a scalar + % in samples per second. This value is constant + SamplingRate = 1e9; + end + + properties (Hidden, Nontunable, Access = protected) + isOutput = true; + end + + properties(Nontunable, Hidden, Constant) + Type = 'Tx'; + channel_names = {'voltage0','voltage1'}; + end + + properties (Nontunable, Hidden) + devName = 'axi-ad9144-hpc'; + end + + methods + %% Constructor + function obj = Tx(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.AD9144.Base(varargin{:}); + 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 = 'AD9144'; + end + + end +end + diff --git a/+adi/+AD9467/Base.m b/+adi/+AD9467/Base.m new file mode 100644 index 00000000..19aa23bd --- /dev/null +++ b/+adi/+AD9467/Base.m @@ -0,0 +1,72 @@ +classdef (Abstract) Base < adi.common.Attribute & ... + matlabshared.libiio.base & ... + matlab.system.mixin.CustomIcon + %AD9467 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 = 'int16'; + phyDevName = 'cf-ad9467-core-lpc'; + 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(['AD9467 ',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 = 'AD9467'; + end + + end +end + diff --git a/+adi/+AD9467/Rx.m b/+adi/+AD9467/Rx.m new file mode 100644 index 00000000..3d0c56da --- /dev/null +++ b/+adi/+AD9467/Rx.m @@ -0,0 +1,163 @@ +classdef Rx < adi.AD9467.Base & adi.common.Rx + % adi.AD9467.Rx Receive data from the AD9467 high speed ADC + % The adi.AD9467.Rx System object is a signal source that can receive + % complex data from the AD9467. + % + % rx = adi.AD9467.Rx; + % rx = adi.AD9467.Rx('uri','192.168.2.1'); + % + % AD9467 Datasheet + + properties (Dependent) + %SamplingRate Sampling Rate + % Baseband sampling rate in Hz, specified as a scalar + % in samples per second. This value read from the hardware after + % the object is setup. + SamplingRate + end + + properties + %TestMode Test Mode + % Select ADC test mode. Options are: + % 'off' + % 'midscale_short' + % 'pos_fullscale' + % 'neg_fullscale' + % 'checkerboard' + % 'pn_long' + % 'pn_short' + % 'one_zero_toggle' + TestMode = 'off'; + %FilterHighPass3dbFrequency Filter High Pass 3db Frequency + % FilterHighPass3dbFrequency + FilterHighPass3dbFrequency = 0; + %Scale Scale + % Scale received data. Possible options are: + % 0.030517 0.032043 0.033569 0.035095 0.036621 0.038146 + Scale = 0.038146; + end + + properties(Constant, Hidden) + TestModeSet = matlab.system.StringSet({ ... + 'off','midscale_short', 'pos_fullscale', 'neg_fullscale',... + 'checkerboard', 'pn_long', 'pn_short', 'one_zero_toggle'}); + end + + properties (Hidden, Nontunable, Access = protected) + isOutput = false; + end + + properties(Nontunable, Hidden, Constant) + Type = 'Rx'; + channel_names = {'voltage0'}; + end + + properties (Nontunable, Hidden) + devName = 'cf-ad9467-core-lpc'; + end + + methods + %% Constructor + function obj = Rx(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.AD9467.Base(varargin{:}); + end + % Check TestMode + function set.TestMode(obj, value) + obj.TestMode = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id,'test_mode',value,false); + end + end + % Check FilterHighPass3dbFrequency + function set.FilterHighPass3dbFrequency(obj, value) + obj.FilterHighPass3dbFrequency = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeLongLong(id,'filter_high_pass_3db_frequency',value,false); + end + end + % Check Scale + function set.Scale(obj, value) + options = [0.030517 0.032043 0.033569 0.035095 0.036621 0.038146]; + if ~any(value==options) + error(['Scale must be one of ',num2str(options)]); + end + obj.Scale = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id,'scale',num2str(value),false); + end + end + function value = get.SamplingRate(obj) + if obj.ConnectedToDevice + id = 'voltage0'; + value = obj.getAttributeLongLong(id,'sampling_frequency',false); + else + value = 0; + end + end + + end + + %% API Functions + methods (Hidden, Access = protected) + + function numOut = getNumOutputsImpl(obj) + numOut = ceil(obj.channelCount) + 1; % +1 for valid + end + + function setupInit(obj) + % Write all attributes to device once connected through set + % methods + id = 'voltage0'; + + obj.setAttributeRAW(id,'test_mode',obj.TestMode,false); + obj.setAttributeLongLong(id,'filter_high_pass_3db_frequency',... + obj.FilterHighPass3dbFrequency,false); + obj.setAttributeRAW(id,'scale',num2str(obj.Scale),false); + + obj.setAttributeLongLong(id,'calibbias',obj.CalibrationBias,... + false); + obj.setAttributeRAW(id,'calibphase',... + num2str(obj.CalibrationPhase),false); + obj.setAttributeRAW(id,'calibscale',... + num2str(obj.CalibrationScale),false); + + + end + + % Hide unused parameters when in specific modes + function flag = isInactivePropertyImpl(obj, prop) + % Call the superclass method + flag = isInactivePropertyImpl@adi.common.RxTx(obj,prop); + end + end + + methods (Access=protected) + + + 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 = 'AD9467'; + end + + end +end + diff --git a/+adi/+AD9680/Base.m b/+adi/+AD9680/Base.m new file mode 100644 index 00000000..ff55e385 --- /dev/null +++ b/+adi/+AD9680/Base.m @@ -0,0 +1,74 @@ +classdef (Abstract) Base < matlabshared.libiio.base & ... + matlab.system.mixin.CustomIcon + %AD9680 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 = 'int16'; + 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(['AD9680 ',obj.Type]); + end + + 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 = 'AD9680'; + end + + end +end + diff --git a/+adi/+AD9680/Rx.m b/+adi/+AD9680/Rx.m new file mode 100644 index 00000000..6ab92980 --- /dev/null +++ b/+adi/+AD9680/Rx.m @@ -0,0 +1,59 @@ +classdef Rx < adi.AD9680.Base & adi.common.Rx + % adi.AD9680.Rx Receive data from the AD9680 high speed ADC + % The adi.AD9680.Rx System object is a signal source that can receive + % complex data from the AD9680. + % + % rx = adi.AD9680.Rx; + % rx = adi.AD9680.Rx('uri','192.168.2.1'); + % + % AD9680 Datasheet + % + % See also adi.DAQ2.Rx + + properties (Constant) + %SamplingRate Sampling Rate + % Baseband sampling rate in Hz, specified as a scalar + % in samples per second. This value is constant + SamplingRate = 1e9; + end + properties (Hidden, Nontunable, Access = protected) + isOutput = false; + end + + properties(Nontunable, Hidden, Constant) + Type = 'Rx'; + channel_names = {'voltage0','voltage1'}; + end + + properties (Nontunable, Hidden) + devName = 'axi-ad9680-hpc'; + end + + methods + %% Constructor + function obj = Rx(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.AD9680.Base(varargin{:}); + 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 = 'AD9680'; + end + + end +end + diff --git a/+adi/+DAQ2/Rx.m b/+adi/+DAQ2/Rx.m new file mode 100644 index 00000000..e0e760fe --- /dev/null +++ b/+adi/+DAQ2/Rx.m @@ -0,0 +1,22 @@ +classdef Rx < adi.AD9680.Rx + % adi.DAQ2.Rx Receive data from the DAQ2 evaluation platform + % The adi.DAQ2.Rx System object is a signal source that can + % receive complex data from the DAQ2. + % + % rx = adi.DAQ2.Rx; + % rx = adi.DAQ2.Rx('uri','192.168.2.1'); + % + % User Guide + % + % See also adi.AD9680.Rx, adi.DAQ2.Tx + methods + %% Constructor + function obj = Rx(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.AD9680.Rx(varargin{:}); + end + end + +end + diff --git a/+adi/+DAQ2/Tx.m b/+adi/+DAQ2/Tx.m new file mode 100644 index 00000000..4be9bf1a --- /dev/null +++ b/+adi/+DAQ2/Tx.m @@ -0,0 +1,22 @@ +classdef Tx < adi.AD9144.Tx + % adi.DAQ2.Tx Transmit data from the DAQ2 evaluation platform + % The adi.DAQ2.Tx System object is a signal source that can + % send complex data to the DAQ2. + % + % tx = adi.DAQ2.Tx; + % tx = adi.DAQ2.Tx('uri','192.168.2.1'); + % + % User Guide + % + % See also adi.AD9144.Tx, adi.DAQ2.Rx + methods + %% Constructor + function obj = Tx(varargin) + % Returns the matlabshared.libiio.base object + coder.allowpcode('plain'); + obj = obj@adi.AD9144.Tx(varargin{:}); + end + end + +end + diff --git a/+adi/+common b/+adi/+common new file mode 160000 index 00000000..60370078 --- /dev/null +++ b/+adi/+common @@ -0,0 +1 @@ +Subproject commit 603700787df6d1848dae5ee288cc897bd15ebf01 diff --git a/+adi/+utils/ADIWorkFlow.m b/+adi/+utils/ADIWorkFlow.m new file mode 100644 index 00000000..fd46b8ff --- /dev/null +++ b/+adi/+utils/ADIWorkFlow.m @@ -0,0 +1,172 @@ +classdef ADIWorkFlow < matlab.hwmgr.internal.hwsetup.Workflow + + properties(Constant) + % Properties inherited from Workflow class + BaseCode = 'ADIBSP'; + end + + properties + % Properties inherited from Workflow class + Name = 'Hardware Setup App for Analog Devices Board Support Packages' + FirstScreenID + ResourceDir + ShowExamples = true; + InstalledUdevRule + DriverInstalled + CompilerConfigured + InstallDriverWorkflow = false + ExpectedFirmwareVersion = '' + CurrentFirmwareVersion = '' + UpdateFirmwareWorkflow = false + UpdateFirmwareSelected = true + HardwareInterface + Testing = false + end + + methods + % Class Constructor + function obj = ADIWorkFlow(varargin) + obj@matlab.hwmgr.internal.hwsetup.Workflow(varargin{:}) + +% obj.HardwareInterface = plutoradio.internal.hwsetup.HardwareInterface; + +% obj.DriverInstalled = ... +% matlab.hwmgr.internal.hwsetup.register.PlutoRadioWorkFlow.checkDriver(); + + determineFirstScreen(obj); + +% obj.ResourceDir = fullfile(plutoradio.internal.getRootDir, 'resources'); + + % Setup MATLAB session for PlutoSDR HSP +% dev = sdrdev('Pluto'); + + % Consider saving path, etc. + + end + + function determineFirstScreen(obj) +% arch = computer('arch'); +% if (obj.DriverInstalled || strcmp(arch, 'maci64')) +% firstScreen = 'plutoradio.internal.hwsetup.ConnectHardware'; +% else +% switch arch +% case 'win64' +% firstScreen = 'plutoradio.internal.hwsetup.InstallDriverWindows'; +% case 'glnxa64' +% firstScreen = 'plutoradio.internal.hwsetup.InstallDriverLinux'; +% end +% end + +% firstScreen = 'adi.InstallDriverLinux'; + + firstScreen = 'adi.Step1'; + obj.FirstScreenID = firstScreen; + end + + function refocus(obj) + f = findall(0, 'type', 'figure', 'Name', 'Hardware Setup'); + idx = strfind(obj.FirstScreenID, '.'); + tag = strrep(obj.FirstScreenID(1:idx(end)), '.', '_'); + for p=1:length(f) + if contains(f(p).Tag, tag) + pause(3); + figure(f(1)); + end + end + end + + function success = isFirmwareCompatible(obj) + success = false; + + [expVer,curVer] = getFirmwareVersion(obj.HardwareInterface); + if isempty(curVer) + errordlg(obj, ... + message('plutoradio:hwsetup:UpdateFirmware_USBSearchFailed', '').getString); + else + obj.CurrentFirmwareVersion = curVer; + obj.ExpectedFirmwareVersion = expVer; + if expVer == curVer + success = true; + end + end + end + + function setSerialNum(obj, serialNum) + obj.HardwareInterface.SerialNum = serialNum; + end + + function serialNum = getSerialNum(obj) + serialNum = obj.HardwareInterface.SerialNum; + end + + function setRadioID(obj, radioID) + obj.HardwareInterface.RadioID = radioID; + end + + function radioID = getRadioID(obj) + radioID = obj.HardwareInterface.RadioID; + end + + function varargout = warndlg(~, msg) + dlgHandle = warndlg(msg, ... + message('plutoradio:hwsetup:UpdateFirmware_Title').getString); + if nargout > 0 + varargout{1} = dlgHandle; + end + end + + function varargout = errordlg(~, msg) + dlgHandle = errordlg(msg, ... + message('plutoradio:hwsetup:UpdateFirmware_Title').getString); + if nargout > 0 + varargout{1} = dlgHandle; + end + end + end + + methods (Static) + function flag = checkDriver() + % Assume driver is installed + flag = true; + + switch computer('arch') + case 'win64' + try + installPath = winqueryreg(... + 'HKEY_LOCAL_MACHINE',... + 'SOFTWARE\Analog Devices\PlutoSDR-M2k-USB-Win-Drivers\Settings',... + 'InstallPath'); %#ok + catch me + if strcmp(me.identifier, 'MATLAB:WINQUERYREG:invalidkey') + flag = false; + end + end + case 'glnxa64' + udevFileName = '90-plutosdr-mw.rules'; + udevFile = fullfile('/lib/udev/rules.d', udevFileName); + if ~exist(udevFile, 'file') + flag = false; + else + % Check the content + expectedContent = sprintf('%s\n%s\n', ... + '# PlutoSDR', ... + ['SUBSYSTEMS=="usb", ATTRS{idVendor}=="0456", '... + 'ATTRS{idProduct}=="b673", MODE:="0666"']); + fid = fopen(udevFile, 'r'); + fileContent = fscanf(fid, '%s', inf); + fclose(fid); + if ~strcmp(replace(expectedContent, {' ', newline}, ''), fileContent) + flag = false; + end + end + case 'maci64' + rootDir = plutoradio.internal.getRootDir; + command = sprintf('%s/bin/maci64/iio_info -s | grep Analog', rootDir); + [status, out] = system(command); + if status || ~contains(out, 'Analog Devices Inc. PlutoSDR (ADALM-PLUTO)') + flag = false; + end + end + end + end +end diff --git a/+adi/+utils/ConnectHardware.m b/+adi/+utils/ConnectHardware.m new file mode 100644 index 00000000..9fe120e0 --- /dev/null +++ b/+adi/+utils/ConnectHardware.m @@ -0,0 +1,113 @@ +classdef ConnectHardware < matlab.hwmgr.internal.hwsetup.ManualConfiguration + % ConnectHardware - Screen implementation to enable users to connect + % the PlutoSDR device to the host + + % Copyright 2017-2018 The MathWorks, Inc. + + properties + end + + methods + function obj = ConnectHardware(varargin) + % Call to the base class constructor + obj@matlab.hwmgr.internal.hwsetup.ManualConfiguration(varargin{:}); + + % Set the Title Text + obj.Title.Text = 'Connect Hardware';%message('plutoradio:hwsetup:ConnectHardwareTitle').getString; + + obj.ConfigurationInstructions.Text = 'Text1'; + %message('plutoradio:hwsetup:ConnectHardware_Instruction').getString; + obj.ConfigurationInstructions.Position = [20 280 430 85]; + + % Increase the Height and Width of the Image before setting the + % ImageFile + obj.ConfigurationImage.ImageFile = fullfile(obj.Workflow.ResourceDir,... + 'adalm-pluto_connect.png'); + obj.ConfigurationImage.addHeight(80); + obj.ConfigurationImage.addWidth(80); + + if isunix + if ~ismac + obj.ConfigurationInstructions.addWidth(15); + end + end + + % Set the HelpText + obj.HelpText.WhatToConsider = [... + message('plutoradio:hwsetup:ConnectHardware_WhatToConsider').getString]; + obj.HelpText.AboutSelection = ''; + obj.HelpText.Additional = ''; + + if strcmp(obj.Workflow.FirstScreenID, class(obj)) + obj.BackButton.Visible = 'off'; + obj.BackButton.Enable = 'off'; + end + + end + + function restoreScreen(obj) + obj.enableScreen(); + end + + function out = getPreviousScreenID(obj) %#ok + switch computer('arch') + case 'win64' + out = 'plutoradio.internal.hwsetup.InstallDriverWindows'; + case 'maci64' + out = ''; + case 'glnxa64' + out = 'plutoradio.internal.hwsetup.InstallDriverLinux'; + end + end + + function out = getNextScreenID(obj) + % Find the connected radio + findRadio(obj); + + % Create a BusyOverlay inside the window + busyOverlay = matlab.hwmgr.internal.hwsetup.BusyOverlay.getInstance(obj.ContentPanel); + busyOverlay.Text = 'Checking firmware version'; + restoreOnCleanup = onCleanup(@()removeOverlay(busyOverlay)); + + % Check radio firmware version + success = isFirmwareCompatible(obj.Workflow); + + logMessage(obj, sprintf('isFirmwareCompatible returned %d', success)); + + if ~success + obj.Workflow.UpdateFirmwareWorkflow = true; + out = 'plutoradio.internal.hwsetup.UnexpectedFirmware'; + else + obj.Workflow.UpdateFirmwareWorkflow = false; + out = 'plutoradio.internal.hwsetup.TestConnection'; + end + end + end + + methods (Access = private) + function findRadio(obj) + radios = getConnectedRadios(obj.Workflow.HardwareInterface); + numRadios = length(radios); + if numRadios == 0 + error(message('plutoradio:hwsetup:ConnectHardware_NoRadio').getString); + elseif numRadios > 1 + error(message('plutoradio:hwsetup:ConnectHardware_MoreThanOneRadio').getString); + else + if isRadioBusy(obj.Workflow.HardwareInterface, radios.RadioID) + error(message('plutoradio:hwsetup:ConnectHardware_RadioBusy', radios.RadioID)); + else + setRadioID(obj.Workflow, radios.RadioID); + setSerialNum(obj.Workflow, radios.SerialNum); + logMessage(obj, ... + sprintf('Found radio with ID: %s and SN: %s', ... + radios.RadioID, radios.SerialNum)); + end + end + end +end +end + +function removeOverlay(busyOverlay) +busyOverlay.Visible = 'off'; +delete(busyOverlay) +end diff --git a/+adi/+utils/Downloader.m b/+adi/+utils/Downloader.m new file mode 100644 index 00000000..9d24c934 --- /dev/null +++ b/+adi/+utils/Downloader.m @@ -0,0 +1,23 @@ +classdef Downloader < adi.utils.libad9361 + + properties (Constant) + PossibleDependencies = {'libad9361'}; + end + + methods + + function download(obj,dep) + if nargin == 0 + fprintf('Specific dependency name on input. Options are:\n%s',obj.PossibleDependencies); + end + switch dep + case 'libad9361' + download_libad9361(obj); + otherwise + error('Unknown dependency %s',dep); + end + end + + end +end + diff --git a/+adi/+utils/InstallDriverBase.m b/+adi/+utils/InstallDriverBase.m new file mode 100644 index 00000000..a2d33286 --- /dev/null +++ b/+adi/+utils/InstallDriverBase.m @@ -0,0 +1,78 @@ +classdef InstallDriverBase < matlab.hwmgr.internal.hwsetup.TemplateBase + +% Copyright 2017 The MathWorks, Inc. + + properties + InfoText1 + InfoText2 + InfoText3 + end + + methods + function obj = InstallDriverBase(varargin) + obj@matlab.hwmgr.internal.hwsetup.TemplateBase(varargin{:}); + + obj.Workflow.InstallDriverWorkflow = true; + + parentContainer = obj.ContentPanel; + + obj.InfoText1 = matlab.hwmgr.internal.hwsetup.Label.getInstance(parentContainer); + obj.InfoText1.Position = [20 290 400 80]; + obj.InfoText1.Text = ''; + obj.InfoText1.Color = matlab.hwmgr.internal.hwsetup.util.Color.WHITE; + + obj.InfoText2 = matlab.hwmgr.internal.hwsetup.Label.getInstance(parentContainer); + obj.InfoText2.Position = [20 230 400 50]; + obj.InfoText2.Text = ''; + obj.InfoText2.Color = matlab.hwmgr.internal.hwsetup.util.Color.WHITE; + + obj.InfoText3 = matlab.hwmgr.internal.hwsetup.Label.getInstance(parentContainer); + obj.InfoText3.Position = [20 170 400 50]; + obj.InfoText3.Text = ''; + obj.InfoText3.Color = matlab.hwmgr.internal.hwsetup.util.Color.WHITE; + + obj.HelpText.AboutSelection = ''; + obj.HelpText.WhatToConsider = ''; + + if strcmp(obj.Workflow.FirstScreenID, class(obj)) + obj.BackButton.Visible = 'off'; + obj.BackButton.Enable = 'off'; + end + end + + function restoreScreen(obj) + obj.enableScreen(); + end + end + + methods (Access = protected, Abstract) + status = installDriverImpl(obj) + end + + methods (Access = protected) + function installDriver(obj) + obj.disableScreen(); + restoreOnCleanup = onCleanup(@obj.restoreScreen); + + p = matlab.hwmgr.internal.hwsetup.Panel.getInstance(obj.ContentPanel); + p.Title = ''; + b = matlab.hwmgr.internal.hwsetup.BusyOverlay.getInstance(p); + b.Text = 'Installing USB driver...'; + b.show(); + deleteOverlayOnCleanup = onCleanup(@()delete(p)); + + [status,msg] = installDriverImpl(obj); + + if status + error(message('plutoradio:hwsetup:DriverInstallFailed', msg)); + end + + refocus(obj.Workflow); + end + + function out = getNextScreenIDImpl(obj) + out = 'adi.ConnectHardware'; + installDriver(obj); + end + end +end diff --git a/+adi/+utils/InstallDriverLinux.m b/+adi/+utils/InstallDriverLinux.m new file mode 100644 index 00000000..25970c56 --- /dev/null +++ b/+adi/+utils/InstallDriverLinux.m @@ -0,0 +1,60 @@ +classdef InstallDriverLinux < adi.InstallDriverBase + +% Copyright 2017 The MathWorks, Inc. + + methods + function obj = InstallDriverLinux(varargin) + obj@adi.InstallDriverBase(varargin{:}); + + obj.Title.Text = 'ADI Board Support Package Installer'; + + obj.InfoText1.Position = [20 340 400 30]; + obj.InfoText1.Text = 'Test1';%message('plutoradio:hwsetup:InstallDriverLinux_InfoText1').getString; + + obj.InfoText2.Position = [20 290 400 50]; + obj.InfoText2.Text = 'Test2';%message('plutoradio:hwsetup:InstallDriverLinux_InfoText2').getString; + + obj.HelpText.AboutSelection = ''; + obj.HelpText.WhatToConsider = 'Test3';%message('plutoradio:hwsetup:InstallDriverLinux_WhatToConsider').getString; + end + + function out = getNextScreenID(obj) + % HSA infrastructure requires a "getNextScreenID" method implemented + % in the leaf class. Otherwise, it renders "Finish" button instead of + % "Next". + out = getNextScreenIDImpl(obj); + end + end + + methods (Access = protected) + function [status,out] = installDriverImpl(obj) + udevFileName = '90-plutosdr-mw.rules'; + udevrules = fullfile(tempdir, udevFileName); + fid = fopen(udevrules, 'wt'); + fprintf(fid, '%s\n%s\n', ... + '# PlutoSDR', ... + ['SUBSYSTEMS=="usb", ATTRS{idVendor}=="0456", '... + 'ATTRS{idProduct}=="b673", MODE:="0666"']); + fclose(fid); + + commandwindow + [status,out] = run(obj.Workflow.HardwareInterface, 'sudo echo', '-echo'); + + if ~status + [status,out] = run(obj.Workflow.HardwareInterface, ['sudo cp ' udevrules ' /lib/udev/rules.d']); + if ~status + [status,out] = run(obj.Workflow.HardwareInterface, 'sudo udevadm control --reload'); + if ~status + [status,out] = run(obj.Workflow.HardwareInterface, 'sudo udevadm trigger'); + end + end + end + run(obj.Workflow.HardwareInterface, sprintf('rm %s', udevrules)); + + if ~status + obj.Workflow.InstalledUdevRule = ... + fullfile('/lib/udev/rules.d', udevFileName); + end + end + end +end \ No newline at end of file diff --git a/+adi/+utils/Step1.m b/+adi/+utils/Step1.m new file mode 100644 index 00000000..f8733faa --- /dev/null +++ b/+adi/+utils/Step1.m @@ -0,0 +1,56 @@ +classdef Step1 < adi.StepBase + + % Copyright 2017 The MathWorks, Inc. + properties (Hidden) + InstallButton + end + + methods + function obj = Step1(varargin) + obj@adi.StepBase(varargin{:}); + + % obj.Workflow.InstallDriverWorkflow = true; + + parentContainer = obj.ContentPanel; + + obj.Title.Text = 'ADI Board Support Package Installer'; + + obj.InfoText1.Position = [20 340 400 30]; + obj.InfoText1.Text = 'Step 1: Installing drivers'; + + obj.InfoText2.Position = [20 290 400 50]; + obj.InfoText2.Text = 'Test2'; + + obj.InstallButton = matlab.hwmgr.internal.hwsetup.Button.getInstance(parentContainer); + obj.InstallButton.ButtonPushedFcn = @obj.LinuxInstall; + obj.InstallButton.Text = 'WINNER'; + + obj.HelpText.AboutSelection = 'About Selection'; + obj.HelpText.WhatToConsider = 'Test3'; + end + + function out = getNextScreenID(obj) + % HSA infrastructure requires a "getNextScreenID" method implemented + % in the leaf class. Otherwise, it renders "Finish" button instead of + % "Next". + out = getNextScreenIDImpl(obj); + end + + function restoreScreen(obj) + obj.enableScreen(); + end + end + + methods (Access = protected) + + function out = getNextScreenIDImpl(~) + out = 'adi.Step2'; + end + + function LinuxInstall(~,~,~) + system('sudo whoami'); + end + + end + +end diff --git a/+adi/+utils/Step2.m b/+adi/+utils/Step2.m new file mode 100644 index 00000000..d8f364d8 --- /dev/null +++ b/+adi/+utils/Step2.m @@ -0,0 +1,43 @@ +classdef Step2 < adi.StepBase + + % Copyright 2017 The MathWorks, Inc. + + methods + function obj = Step2(varargin) + obj@adi.StepBase(varargin{:}); + + % obj.Workflow.InstallDriverWorkflow = true; + + obj.Title.Text = 'ADI Board Support Package Installer: Step2'; + + obj.InfoText1.Position = [20 340 400 30]; + obj.InfoText1.Text = 'Test1: Step2'; + + obj.InfoText2.Position = [20 290 400 50]; + obj.InfoText2.Text = 'Test2: Step2'; + + obj.HelpText.AboutSelection = 'About Selection: Step2'; + obj.HelpText.WhatToConsider = 'Test3: Step2'; + end + + function out = getNextScreenID(obj) + % HSA infrastructure requires a "getNextScreenID" method implemented + % in the leaf class. Otherwise, it renders "Finish" button instead of + % "Next". + out = getNextScreenIDImpl(obj); + end + + function restoreScreen(obj) + obj.enableScreen(); + end + end + + methods (Access = protected) + + function out = getNextScreenIDImpl(~) + out = 'adi.Step3'; + end + + end + +end diff --git a/+adi/+utils/Step3.m b/+adi/+utils/Step3.m new file mode 100644 index 00000000..6153fe0c --- /dev/null +++ b/+adi/+utils/Step3.m @@ -0,0 +1,43 @@ +classdef Step3 < adi.StepBase + + % Copyright 2017 The MathWorks, Inc. + + methods + function obj = Step3(varargin) + obj@adi.StepBase(varargin{:}); + + % obj.Workflow.InstallDriverWorkflow = true; + + obj.Title.Text = 'ADI Board Support Package Installer: Step3'; + + obj.InfoText1.Position = [20 340 400 30]; + obj.InfoText1.Text = 'Test1: Step3'; + + obj.InfoText2.Position = [20 290 400 50]; + obj.InfoText2.Text = 'Test2: Step3'; + + obj.HelpText.AboutSelection = 'About Selection: Step3'; + obj.HelpText.WhatToConsider = 'Test3: Step3'; + end + +% function out = getNextScreenID(obj) +% % HSA infrastructure requires a "getNextScreenID" method implemented +% % in the leaf class. Otherwise, it renders "Finish" button instead of +% % "Next". +% out = getNextScreenIDImpl(obj); +% end + + function restoreScreen(obj) + obj.enableScreen(); + end + end + + methods (Access = protected) + + function out = getNextScreenIDImpl(~) + out = 'adi.Step3'; + end + + end + +end diff --git a/+adi/+utils/StepBase.m b/+adi/+utils/StepBase.m new file mode 100644 index 00000000..cbe5e8c4 --- /dev/null +++ b/+adi/+utils/StepBase.m @@ -0,0 +1,49 @@ +classdef StepBase < matlab.hwmgr.internal.hwsetup.TemplateBase + + properties + InfoText1 + InfoText2 + InfoText3 + end + + methods + function obj = StepBase(varargin) + obj@matlab.hwmgr.internal.hwsetup.TemplateBase(varargin{:}); + + parentContainer = obj.ContentPanel; + + obj.InfoText1 = matlab.hwmgr.internal.hwsetup.Label.getInstance(parentContainer); + obj.InfoText1.Position = [20 290 400 80]; + obj.InfoText1.Text = ''; + obj.InfoText1.Color = matlab.hwmgr.internal.hwsetup.util.Color.WHITE; + + obj.InfoText2 = matlab.hwmgr.internal.hwsetup.Label.getInstance(parentContainer); + obj.InfoText2.Position = [20 230 400 50]; + obj.InfoText2.Text = ''; + obj.InfoText2.Color = matlab.hwmgr.internal.hwsetup.util.Color.WHITE; + + obj.InfoText3 = matlab.hwmgr.internal.hwsetup.Label.getInstance(parentContainer); + obj.InfoText3.Position = [20 170 400 50]; + obj.InfoText3.Text = ''; + obj.InfoText3.Color = matlab.hwmgr.internal.hwsetup.util.Color.WHITE; + + + obj.HelpText.AboutSelection = ''; + obj.HelpText.WhatToConsider = ''; + + if strcmp(obj.Workflow.FirstScreenID, class(obj)) + obj.BackButton.Visible = 'off'; + obj.BackButton.Enable = 'off'; + end + end + + function restoreScreen(obj) + obj.enableScreen(); + end + end + +% methods (Access = protected, Abstract) +% status = installDriverImpl(obj) +% end + +end diff --git a/+adi/+utils/libad9361.m b/+adi/+utils/libad9361.m new file mode 100644 index 00000000..b1a34eeb --- /dev/null +++ b/+adi/+utils/libad9361.m @@ -0,0 +1,112 @@ +classdef libad9361 < handle + + properties (Hidden) + libad9361_win = 'https://github.com/analogdevicesinc/libad9361-iio/releases/download/v0.2/libad9361-0.2-win64.zip'; + libad9361_osx = 'https://github.com/analogdevicesinc/libad9361-iio/releases/download/v0.2/ad9361-0.2-Darwin.tar.gz'; + libad9361_linux= 'http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-trusty.tar.gz'; + os + headerFileNames = {'ad9361.h','ad9361-wrapper.h'}; + libraryFileNames = {'ad9361','libad9361.so','libad9361.dll'}; + tmpdir = 'tmp_deps_install'; + end + + methods (Access=protected, Hidden) + + function loc = getDependencyTargetLocation(~) + rootDir = fileparts(strtok(mfilename('fullpath'), '+')); + loc = fullfile(rootDir,'deps','ad9361'); + end + + function [files,dlfn,fulltmp] = downloadFiles(obj) + if ismac + dlfn = websave('dl.tar.gz',obj.libad9361_osx); + fulltmp = fullfile(pwd,obj.tmpdir); + files = untar(dlfn,fulltmp); + elseif ispc + dlfn = websave('dl.zip',obj.libad9361_win); + fulltmp = fullfile(pwd,obj.tmpdir); + files = unzip(dlfn,fulltmp); + else + dlfn = websave('dl.tar.gz',obj.libad9361_linux); + fulltmp = fullfile(pwd,obj.tmpdir); + files = untar(dlfn,fulltmp); + end + end + + end + + methods + + function [check,lib,head] = checkForDependencies(obj) + loc = getDependencyTargetLocation(obj); + lib = false; + for l = 1:length(obj.libraryFileNames) + lib = lib || exist(fullfile(loc,obj.libraryFileNames{l}),'file'); + end + head = true; + for h = 1:length(obj.headerFileNames) + head = head && exist(fullfile(loc,'include',obj.headerFileNames{h}),'file'); + end + check = lib && head; + end + + function download_libad9361(obj) + if obj.checkForDependencies() + fprintf('Dependencies already installed, not reinstalling\n'); + return + end + fprintf('Downloading libad9361 library\n'); + [files,dlfn,fulltmp] = downloadFiles(obj); + target = obj.getDependencyTargetLocation(); + if ~exist(target,'dir') + mkdir(target); + end + if ~exist(fullfile(target,'include'),'dir') + mkdir(fullfile(target,'include')); + end + % Includes + for f = 1:length(files) + if contains(files{f},obj.headerFileNames) + copyfile(files{f},fullfile(target,'include')); + end + end + % Libraries + for f = 1:length(files) + if exist(files{f},'dir') + continue; + end + fp = split(files{f}, '/'); fp = fp{end}; + s = dir(files{f}); + if contains(fp,obj.libraryFileNames) && s.bytes>0 + if ismac && ~contains(fp,'.') + copyfile(files{f},fullfile(target,'libad9361.dylib')); + end + if ispc && contains(files{f},'.dll') + copyfile(files{f},target); + end + if isunix + copyfile(files{f},fullfile(target,'libad9361.so')); + end + end + end + % Cleanup + rmdir(fulltmp,'s'); + delete(dlfn); + fprintf('Installing libad9361 complete\n'); + % Path stuff + fprintf('Adding libad9361 to path\n'); + addpath(genpath(target)); + try + warning('error','MATLAB:SavePath:PathNotSaved'); + savepath(); + catch + warning(['savepath failed. libad9361 is currently on path, '... + 'but is likely to not be across MATLAB restarts.',... + 'Please add "',target,'" to path']); + end + end + end +end + + + diff --git a/+adi/Contents.m b/+adi/Contents.m new file mode 100644 index 00000000..dfdf85ef --- /dev/null +++ b/+adi/Contents.m @@ -0,0 +1,15 @@ +% Analog Devices, Inc. High Speed Converter Toolbox +% Version 19.1,1 (R2019a) +% +% ==== Table of Contents (TOC) ==== +% +% Parts +% ----------------------- +% AD9144 - High speed DAC +% AD9680 - High speed ADC +% AD9467 - High speed ADC +% +% Boards and Platforms +% ----------------------- +% DAQ2 - FMC development board for high speed data acquisition + diff --git a/+adi/Version.m b/+adi/Version.m new file mode 100644 index 00000000..70282000 --- /dev/null +++ b/+adi/Version.m @@ -0,0 +1,20 @@ +classdef Version + %Version + % BSP Version information + properties(Constant) + HDL = 'hdl_2018_r2'; + Vivado = '2012.8.1'; + MATLAB = 'R2019a'; + Release = '19.1.1'; + end + properties(Dependent) + VivadoShort + end + + methods + function value = get.VivadoShort(obj) + value = obj.Vivado(1:6); + end + end +end + diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..02778418 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.mlappinstall +*.mexw64 +**/slprj/** +AD9361_Filter_Wizard/*TestFiltWiz*.m +AD9361_Filter_Wizard/.previous_ip_addr diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..613329ce --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,111 @@ +stages: + - build + - test_hdl + - test_synth + - test_hardware + - deploy + +variables: + GIT_SUBMODULE_STRATEGY: recursive + +# Templates +.hdl_tests: + tags: + - vivado + - matlab + stage: test_hdl + dependencies: + - build:master + artifacts: + when: always + name: "$CI_COMMIT_REF_NAME" + paths: + - test/logs/ + - test/BINS/ + - Report.pdf + reports: + junit: test/BSPTestResults.xml + +# Default build +build:master: + tags: + - matlab + stage: build + script: + - export MLRELEASE=R2019a + - export INCLUDE_EXAMPLES=1 + - ./CI/scripts/dockermake build + - ./CI/scripts/dockermake gen_tlbx + - mkdir mltbx + - ls *.mltbx + - cp *.mltbx mltbx/ + artifacts: + when: always + paths: + - hdl/ + - mltbx/ + +# Test HWA no install DAQ2 +test_hdl:DAQ2: + extends: .hdl_tests + script: + - export MLRELEASE=R2019a + - export BOARD=daq2 + - ./CI/scripts/dockermake test + +# Test fully sythesized design +test_synth:Synthesize: + extends: .hdl_tests + stage: test_synth + script: + - export MLRELEASE=R2019a + - export BOARD=daq2 + - ./CI/scripts/dockermake test_synth + +# Test BOOT.BINS +test_hardware:DAQ2_BOOT_BIN_Load: + tags: + - hardware + stage: test_hardware + dependencies: + - test_synth:Synthesize + script: + - git clone https://github.com/tfcollins/fpga-tests.git + - cd fpga-tests + - bash process_boot_bin.sh daq2 + artifacts: + when: always + paths: + - fpga-tests/*.log + +# Test streaming interfaces with hardware +test_hardware:Streaming_Hardware: + tags: + - matlab + - hardware + stage: test_hardware + dependencies: + - build:master + script: + - export MLRELEASE=R2019a + - make -C CI/scripts test_streaming + artifacts: + when: always + paths: + - logs/ + - Report.pdf + +# Deploy +deploy: + tags: + - matlab + stage: deploy + dependencies: + - build:master + script: + - echo "Complete" + artifacts: + paths: + - mltbx/ + + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..f578adf8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "+adi/+common"] + path = +adi/+common + url = https://github.com/analogdevicesinc/ToolboxCommon.git + branch = master diff --git a/CI/doc/ADI_Logo_AWP_Large.png b/CI/doc/ADI_Logo_AWP_Large.png new file mode 100755 index 00000000..7a11a0c8 Binary files /dev/null and b/CI/doc/ADI_Logo_AWP_Large.png differ diff --git a/CI/doc/Examples.mlx b/CI/doc/Examples.mlx new file mode 100644 index 00000000..2905797f Binary files /dev/null and b/CI/doc/Examples.mlx differ diff --git a/CI/doc/Support.mlx b/CI/doc/Support.mlx new file mode 100644 index 00000000..c929c531 Binary files /dev/null and b/CI/doc/Support.mlx differ diff --git a/CI/doc/SupportedHardware.mlx b/CI/doc/SupportedHardware.mlx new file mode 100644 index 00000000..379b2300 Binary files /dev/null and b/CI/doc/SupportedHardware.mlx differ diff --git a/CI/doc/SystemObjects.mlx b/CI/doc/SystemObjects.mlx new file mode 100644 index 00000000..ea34d3a5 Binary files /dev/null and b/CI/doc/SystemObjects.mlx differ diff --git a/CI/doc/adi_bsp.mlx b/CI/doc/adi_bsp.mlx new file mode 100644 index 00000000..678736a1 Binary files /dev/null and b/CI/doc/adi_bsp.mlx differ diff --git a/CI/doc/genhtml.m b/CI/doc/genhtml.m new file mode 100644 index 00000000..67b6b9bc --- /dev/null +++ b/CI/doc/genhtml.m @@ -0,0 +1,20 @@ +[filepath,name,ext] = fileparts(mfilename('fullpath')); +cd(filepath); +files = dir(filepath); + +target = '../../doc/'; + +skip = {'NA'}; + +for f = {files.name} + if strfind(f{:},'.mlx')>=0 + filename = f{:}; + if contains(filename,skip) + continue; + end + htmlFilename = [filename(1:end-4),'.html']; + disp(htmlFilename); + matlab.internal.liveeditor.openAndConvert(filename,htmlFilename); + movefile(htmlFilename,target); + end +end diff --git a/CI/projects/common/boot/bl31.elf b/CI/projects/common/boot/bl31.elf new file mode 100644 index 00000000..7e8295a9 Binary files /dev/null and b/CI/projects/common/boot/bl31.elf differ diff --git a/CI/projects/common/boot/fsbl.elf b/CI/projects/common/boot/fsbl.elf new file mode 100755 index 00000000..2fb6b95c Binary files /dev/null and b/CI/projects/common/boot/fsbl.elf differ diff --git a/CI/projects/common/boot/pmufw.elf b/CI/projects/common/boot/pmufw.elf new file mode 100755 index 00000000..b4ff0452 Binary files /dev/null and b/CI/projects/common/boot/pmufw.elf differ diff --git a/CI/projects/common/boot/u-boot-zcu.elf b/CI/projects/common/boot/u-boot-zcu.elf new file mode 100644 index 00000000..d4edf69c Binary files /dev/null and b/CI/projects/common/boot/u-boot-zcu.elf differ diff --git a/CI/projects/common/boot/zynq.bif b/CI/projects/common/boot/zynq.bif new file mode 100644 index 00000000..235acaa4 --- /dev/null +++ b/CI/projects/common/boot/zynq.bif @@ -0,0 +1,6 @@ +the_ROM_image: +{ +[bootloader]./fsbl.elf +./system_top.bit +./u-boot.elf +} diff --git a/CI/projects/common/boot/zynqmp.bif b/CI/projects/common/boot/zynqmp.bif new file mode 100644 index 00000000..a86aa22f --- /dev/null +++ b/CI/projects/common/boot/zynqmp.bif @@ -0,0 +1,8 @@ +the_ROM_image: +{ +[pmufw_image] ./pmufw.elf +[bootloader,destination_cpu=a53-0] ./fsbl.elf +[destination_device=pl] ./system_top.bit +[destination_cpu=a53-0,exception_level=el-3,trustzone] ./bl31.elf +[destination_cpu=a53-0,exception_level=el-2] ./u-boot-zcu.elf +} diff --git a/CI/projects/common/xilinx/adcfifo_bd.tcl b/CI/projects/common/xilinx/adcfifo_bd.tcl new file mode 100644 index 00000000..6d5eabe5 --- /dev/null +++ b/CI/projects/common/xilinx/adcfifo_bd.tcl @@ -0,0 +1,10 @@ +# sys bram (use only when dma is not capable of keeping up). +# generic fifo interface - existence is oblivious to software. + +ad_ip_instance util_adcfifo $adc_fifo_name +ad_ip_parameter $adc_fifo_name CONFIG.ADC_DATA_WIDTH $adc_data_width +ad_ip_parameter $adc_fifo_name CONFIG.DMA_DATA_WIDTH $adc_dma_data_width +ad_ip_parameter $adc_fifo_name CONFIG.DMA_READY_ENABLE 1 +ad_ip_parameter $adc_fifo_name CONFIG.DMA_ADDRESS_WIDTH $adc_fifo_address_width + + diff --git a/CI/projects/common/xilinx/dacfifo_bd.tcl b/CI/projects/common/xilinx/dacfifo_bd.tcl new file mode 100644 index 00000000..4a5397c2 --- /dev/null +++ b/CI/projects/common/xilinx/dacfifo_bd.tcl @@ -0,0 +1,11 @@ +# sys bram (use only when dma is not capable of keeping up). +# generic fifo interface - existence is oblivious to software. + +if {$dac_data_width != $dac_dma_data_width} { + return -code error [format "ERROR: util_dacfifo dac/dma widths must be the same!"] +} + +ad_ip_instance util_dacfifo $dac_fifo_name +ad_ip_parameter $dac_fifo_name CONFIG.DATA_WIDTH $dac_data_width +ad_ip_parameter $dac_fifo_name CONFIG.ADDRESS_WIDTH $dac_fifo_address_width + diff --git a/CI/projects/common/zcu102/zcu102_system_bd.tcl b/CI/projects/common/zcu102/zcu102_system_bd.tcl new file mode 100644 index 00000000..00acef46 --- /dev/null +++ b/CI/projects/common/zcu102/zcu102_system_bd.tcl @@ -0,0 +1,125 @@ + +# create board design +# default ports + +create_bd_port -dir O -from 2 -to 0 spi0_csn +create_bd_port -dir O spi0_sclk +create_bd_port -dir O spi0_mosi +create_bd_port -dir I spi0_miso + +create_bd_port -dir O -from 2 -to 0 spi1_csn +create_bd_port -dir O spi1_sclk +create_bd_port -dir O spi1_mosi +create_bd_port -dir I spi1_miso + +create_bd_port -dir I -from 94 -to 0 gpio_i +create_bd_port -dir O -from 94 -to 0 gpio_o +create_bd_port -dir O -from 94 -to 0 gpio_t + +# instance: sys_ps8 + +ad_ip_instance zynq_ultra_ps_e sys_ps8 +apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e \ + -config {apply_board_preset 1} [get_bd_cells sys_ps8] + +ad_ip_parameter sys_ps8 CONFIG.PSU__USE__M_AXI_GP0 0 +ad_ip_parameter sys_ps8 CONFIG.PSU__USE__M_AXI_GP1 0 +ad_ip_parameter sys_ps8 CONFIG.PSU__USE__M_AXI_GP2 1 +ad_ip_parameter sys_ps8 CONFIG.PSU__MAXIGP2__DATA_WIDTH 32 +ad_ip_parameter sys_ps8 CONFIG.PSU__FPGA_PL0_ENABLE 1 +ad_ip_parameter sys_ps8 CONFIG.PSU__CRL_APB__PL0_REF_CTRL__SRCSEL {IOPLL} +ad_ip_parameter sys_ps8 CONFIG.PSU__CRL_APB__PL0_REF_CTRL__FREQMHZ 100 +ad_ip_parameter sys_ps8 CONFIG.PSU__FPGA_PL1_ENABLE 1 +ad_ip_parameter sys_ps8 CONFIG.PSU__CRL_APB__PL1_REF_CTRL__SRCSEL {IOPLL} +ad_ip_parameter sys_ps8 CONFIG.PSU__CRL_APB__PL1_REF_CTRL__FREQMHZ 200 +ad_ip_parameter sys_ps8 CONFIG.PSU__USE__IRQ0 1 +ad_ip_parameter sys_ps8 CONFIG.PSU__USE__IRQ1 1 +ad_ip_parameter sys_ps8 CONFIG.PSU__GPIO_EMIO__PERIPHERAL__ENABLE 1 + +set_property -dict [list \ + CONFIG.PSU__SPI0__PERIPHERAL__ENABLE 1 \ + CONFIG.PSU__SPI0__PERIPHERAL__IO {EMIO} \ + CONFIG.PSU__SPI0__GRP_SS1__ENABLE 1 \ + CONFIG.PSU__SPI0__GRP_SS2__ENABLE 1 \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__FREQMHZ 100 \ + CONFIG.PSU__SPI1__PERIPHERAL__ENABLE 1 \ + CONFIG.PSU__SPI1__PERIPHERAL__IO EMIO \ + CONFIG.PSU__SPI1__GRP_SS1__ENABLE 1 \ + CONFIG.PSU__SPI1__GRP_SS2__ENABLE 1 \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__FREQMHZ 100 \ +] [get_bd_cells sys_ps8] + +ad_ip_instance proc_sys_reset sys_rstgen +ad_ip_parameter sys_rstgen CONFIG.C_EXT_RST_WIDTH 1 + +# system reset/clock definitions + +ad_connect sys_cpu_clk sys_ps8/pl_clk0 +ad_connect sys_200m_clk sys_ps8/pl_clk1 +ad_connect sys_cpu_reset sys_rstgen/peripheral_reset +ad_connect sys_cpu_resetn sys_rstgen/peripheral_aresetn +ad_connect sys_cpu_clk sys_rstgen/slowest_sync_clk +ad_connect sys_ps8/pl_resetn0 sys_rstgen/ext_reset_in + +# gpio + +ad_connect gpio_i sys_ps8/emio_gpio_i +ad_connect gpio_o sys_ps8/emio_gpio_o +ad_connect gpio_t sys_ps8/emio_gpio_t + +# spi + +ad_ip_instance xlconcat spi0_csn_concat +ad_ip_parameter spi0_csn_concat CONFIG.NUM_PORTS 3 +ad_connect sys_ps8/emio_spi0_ss_o_n spi0_csn_concat/In0 +ad_connect sys_ps8/emio_spi0_ss1_o_n spi0_csn_concat/In1 +ad_connect sys_ps8/emio_spi0_ss2_o_n spi0_csn_concat/In2 +ad_connect spi0_csn_concat/dout spi0_csn +ad_connect sys_ps8/emio_spi0_sclk_o spi0_sclk +ad_connect sys_ps8/emio_spi0_m_o spi0_mosi +ad_connect sys_ps8/emio_spi0_m_i spi0_miso +ad_connect sys_ps8/emio_spi0_ss_i_n VCC +ad_connect sys_ps8/emio_spi0_sclk_i GND +ad_connect sys_ps8/emio_spi0_s_i GND + +ad_ip_instance xlconcat spi1_csn_concat +ad_ip_parameter spi1_csn_concat CONFIG.NUM_PORTS 3 +ad_connect sys_ps8/emio_spi1_ss_o_n spi1_csn_concat/In0 +ad_connect sys_ps8/emio_spi1_ss1_o_n spi1_csn_concat/In1 +ad_connect sys_ps8/emio_spi1_ss2_o_n spi1_csn_concat/In2 +ad_connect spi1_csn_concat/dout spi1_csn +ad_connect sys_ps8/emio_spi1_sclk_o spi1_sclk +ad_connect sys_ps8/emio_spi1_m_o spi1_mosi +ad_connect sys_ps8/emio_spi1_m_i spi1_miso +ad_connect sys_ps8/emio_spi1_ss_i_n VCC +ad_connect sys_ps8/emio_spi1_sclk_i GND +ad_connect sys_ps8/emio_spi1_s_i GND + +# interrupts + +ad_ip_instance xlconcat sys_concat_intc_0 +ad_ip_parameter sys_concat_intc_0 CONFIG.NUM_PORTS 8 + +ad_ip_instance xlconcat sys_concat_intc_1 +ad_ip_parameter sys_concat_intc_1 CONFIG.NUM_PORTS 8 + +ad_connect sys_concat_intc_0/dout sys_ps8/pl_ps_irq0 +ad_connect sys_concat_intc_1/dout sys_ps8/pl_ps_irq1 + +ad_connect sys_concat_intc_1/In7 GND +ad_connect sys_concat_intc_1/In6 GND +ad_connect sys_concat_intc_1/In5 GND +ad_connect sys_concat_intc_1/In4 GND +ad_connect sys_concat_intc_1/In3 GND +ad_connect sys_concat_intc_1/In2 GND +ad_connect sys_concat_intc_1/In1 GND +ad_connect sys_concat_intc_1/In0 GND +ad_connect sys_concat_intc_0/In7 GND +ad_connect sys_concat_intc_0/In6 GND +ad_connect sys_concat_intc_0/In5 GND +ad_connect sys_concat_intc_0/In4 GND +ad_connect sys_concat_intc_0/In3 GND +ad_connect sys_concat_intc_0/In2 GND +ad_connect sys_concat_intc_0/In1 GND +ad_connect sys_concat_intc_0/In0 GND + diff --git a/CI/projects/common/zcu102/zcu102_system_constr.xdc b/CI/projects/common/zcu102/zcu102_system_constr.xdc new file mode 100644 index 00000000..9ea35c41 --- /dev/null +++ b/CI/projects/common/zcu102/zcu102_system_constr.xdc @@ -0,0 +1,27 @@ + +# constraints +# gpio (switches, leds and such) + +set_property -dict {PACKAGE_PIN AN14 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[0]] ; ## GPIO_DIP_SW0 +set_property -dict {PACKAGE_PIN AP14 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[1]] ; ## GPIO_DIP_SW1 +set_property -dict {PACKAGE_PIN AM14 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[2]] ; ## GPIO_DIP_SW2 +set_property -dict {PACKAGE_PIN AN13 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[3]] ; ## GPIO_DIP_SW3 +set_property -dict {PACKAGE_PIN AN12 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[4]] ; ## GPIO_DIP_SW4 +set_property -dict {PACKAGE_PIN AP12 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[5]] ; ## GPIO_DIP_SW5 +set_property -dict {PACKAGE_PIN AL13 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[6]] ; ## GPIO_DIP_SW6 +set_property -dict {PACKAGE_PIN AK13 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[7]] ; ## GPIO_DIP_SW7 +set_property -dict {PACKAGE_PIN AE14 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[8]] ; ## GPIO_SW_E +set_property -dict {PACKAGE_PIN AE15 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[9]] ; ## GPIO_SW_S +set_property -dict {PACKAGE_PIN AG15 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[10]] ; ## GPIO_SW_N +set_property -dict {PACKAGE_PIN AF15 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[11]] ; ## GPIO_SW_W +set_property -dict {PACKAGE_PIN AG13 IOSTANDARD LVCMOS33} [get_ports gpio_bd_i[12]] ; ## GPIO_SW_C + +set_property -dict {PACKAGE_PIN AG14 IOSTANDARD LVCMOS33} [get_ports gpio_bd_o[0]] ; ## GPIO_LED_0 +set_property -dict {PACKAGE_PIN AF13 IOSTANDARD LVCMOS33} [get_ports gpio_bd_o[1]] ; ## GPIO_LED_1 +set_property -dict {PACKAGE_PIN AE13 IOSTANDARD LVCMOS33} [get_ports gpio_bd_o[2]] ; ## GPIO_LED_2 +set_property -dict {PACKAGE_PIN AJ14 IOSTANDARD LVCMOS33} [get_ports gpio_bd_o[3]] ; ## GPIO_LED_3 +set_property -dict {PACKAGE_PIN AJ15 IOSTANDARD LVCMOS33} [get_ports gpio_bd_o[4]] ; ## GPIO_LED_4 +set_property -dict {PACKAGE_PIN AH13 IOSTANDARD LVCMOS33} [get_ports gpio_bd_o[5]] ; ## GPIO_LED_5 +set_property -dict {PACKAGE_PIN AH14 IOSTANDARD LVCMOS33} [get_ports gpio_bd_o[6]] ; ## GPIO_LED_6 +set_property -dict {PACKAGE_PIN AL12 IOSTANDARD LVCMOS33} [get_ports gpio_bd_o[7]] ; ## GPIO_LED_7 + diff --git a/CI/projects/daq2/Makefile b/CI/projects/daq2/Makefile new file mode 100644 index 00000000..4af18d6e --- /dev/null +++ b/CI/projects/daq2/Makefile @@ -0,0 +1,6 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +include ../scripts/project-toplevel.mk diff --git a/CI/projects/daq2/common/config_rxtx.tcl b/CI/projects/daq2/common/config_rxtx.tcl new file mode 100644 index 00000000..341a1c1c --- /dev/null +++ b/CI/projects/daq2/common/config_rxtx.tcl @@ -0,0 +1,38 @@ +global ref_design +global fpga_board + +if {$ref_design eq "Rx" || $ref_design eq "Rx & Tx"} { + # Disconnect the ADC PACK pins + disconnect_bd_net /axi_ad9680_core_adc_valid_0 [get_bd_pins axi_ad9680_cpack/adc_valid_0] + disconnect_bd_net /axi_ad9680_core_adc_valid_1 [get_bd_pins axi_ad9680_cpack/adc_valid_1] + + disconnect_bd_net /axi_ad9680_core_adc_data_0 [get_bd_pins axi_ad9680_cpack/adc_data_0] + disconnect_bd_net /axi_ad9680_core_adc_data_1 [get_bd_pins axi_ad9680_cpack/adc_data_1] + + # Connect the ADC PACK valid signals together + connect_bd_net [get_bd_pins axi_ad9680_cpack/adc_valid_0] [get_bd_pins axi_ad9680_cpack/adc_valid_1] +} + +######################## + +if {$ref_design eq "Tx" || $ref_design eq "Rx & Tx"} { + # Disconnect the DAC PACK pins + # VALID PINS NOT CONNECTED TO INTERFACE CORE ON DAC SIDE + + # DATA PINS + disconnect_bd_net /axi_ad9144_upack_dac_data_0 [get_bd_pins axi_ad9144_core/dac_ddata_0] + disconnect_bd_net /axi_ad9144_upack_dac_data_1 [get_bd_pins axi_ad9144_core/dac_ddata_1] + +} + +# Connect clock +if {$fpga_board eq "ZCU102"} { + + if {$ref_design eq "Rx" || $ref_design eq "Rx & Tx"} { + connect_bd_net [get_bd_pins axi_cpu_interconnect/M08_ACLK] [get_bd_pins util_daq2_xcvr/rx_out_clk_0] + } + + if {$ref_design eq "Tx"} { + connect_bd_net [get_bd_pins axi_cpu_interconnect/M08_ACLK] [get_bd_pins util_daq2_xcvr/tx_out_clk_0] + } +} \ No newline at end of file diff --git a/CI/projects/daq2/common/daq2_bd.tcl b/CI/projects/daq2/common/daq2_bd.tcl new file mode 100644 index 00000000..4a10871a --- /dev/null +++ b/CI/projects/daq2/common/daq2_bd.tcl @@ -0,0 +1,171 @@ + +source $ad_hdl_dir/library/jesd204/scripts/jesd204.tcl + +# dac peripherals + +ad_ip_instance axi_adxcvr axi_ad9144_xcvr +ad_ip_parameter axi_ad9144_xcvr CONFIG.NUM_OF_LANES 4 +ad_ip_parameter axi_ad9144_xcvr CONFIG.QPLL_ENABLE 1 +ad_ip_parameter axi_ad9144_xcvr CONFIG.TX_OR_RX_N 1 + +adi_axi_jesd204_tx_create axi_ad9144_jesd 4 + +ad_ip_instance axi_ad9144 axi_ad9144_core +ad_ip_parameter axi_ad9144_core CONFIG.QUAD_OR_DUAL_N 0 + +ad_ip_instance util_upack axi_ad9144_upack +ad_ip_parameter axi_ad9144_upack CONFIG.CHANNEL_DATA_WIDTH 64 +ad_ip_parameter axi_ad9144_upack CONFIG.NUM_OF_CHANNELS 2 + +ad_ip_instance axi_dmac axi_ad9144_dma +ad_ip_parameter axi_ad9144_dma CONFIG.DMA_TYPE_SRC 0 +ad_ip_parameter axi_ad9144_dma CONFIG.DMA_TYPE_DEST 1 +ad_ip_parameter axi_ad9144_dma CONFIG.ID 1 +ad_ip_parameter axi_ad9144_dma CONFIG.AXI_SLICE_SRC 0 +ad_ip_parameter axi_ad9144_dma CONFIG.AXI_SLICE_DEST 0 +ad_ip_parameter axi_ad9144_dma CONFIG.DMA_LENGTH_WIDTH 24 +ad_ip_parameter axi_ad9144_dma CONFIG.DMA_2D_TRANSFER 0 +ad_ip_parameter axi_ad9144_dma CONFIG.CYCLIC 0 +ad_ip_parameter axi_ad9144_dma CONFIG.DMA_DATA_WIDTH_SRC 128 +ad_ip_parameter axi_ad9144_dma CONFIG.DMA_DATA_WIDTH_DEST 128 + +# adc peripherals + +ad_ip_instance axi_adxcvr axi_ad9680_xcvr +ad_ip_parameter axi_ad9680_xcvr CONFIG.NUM_OF_LANES 4 +ad_ip_parameter axi_ad9680_xcvr CONFIG.QPLL_ENABLE 0 +ad_ip_parameter axi_ad9680_xcvr CONFIG.TX_OR_RX_N 0 + +adi_axi_jesd204_rx_create axi_ad9680_jesd 4 + +ad_ip_instance axi_ad9680 axi_ad9680_core + +ad_ip_instance util_cpack axi_ad9680_cpack +ad_ip_parameter axi_ad9680_cpack CONFIG.CHANNEL_DATA_WIDTH 64 +ad_ip_parameter axi_ad9680_cpack CONFIG.NUM_OF_CHANNELS 2 + +ad_ip_instance axi_dmac axi_ad9680_dma +ad_ip_parameter axi_ad9680_dma CONFIG.DMA_TYPE_SRC 1 +ad_ip_parameter axi_ad9680_dma CONFIG.DMA_TYPE_DEST 0 +ad_ip_parameter axi_ad9680_dma CONFIG.ID 0 +ad_ip_parameter axi_ad9680_dma CONFIG.AXI_SLICE_SRC 0 +ad_ip_parameter axi_ad9680_dma CONFIG.AXI_SLICE_DEST 0 +ad_ip_parameter axi_ad9680_dma CONFIG.SYNC_TRANSFER_START 0 +ad_ip_parameter axi_ad9680_dma CONFIG.DMA_LENGTH_WIDTH 24 +ad_ip_parameter axi_ad9680_dma CONFIG.DMA_2D_TRANSFER 0 +ad_ip_parameter axi_ad9680_dma CONFIG.CYCLIC 0 +ad_ip_parameter axi_ad9680_dma CONFIG.DMA_DATA_WIDTH_SRC 64 +ad_ip_parameter axi_ad9680_dma CONFIG.DMA_DATA_WIDTH_DEST 64 + +# shared transceiver core + +ad_ip_instance util_adxcvr util_daq2_xcvr +ad_ip_parameter util_daq2_xcvr CONFIG.RX_NUM_OF_LANES 4 +ad_ip_parameter util_daq2_xcvr CONFIG.TX_NUM_OF_LANES 4 +ad_ip_parameter util_daq2_xcvr CONFIG.QPLL_REFCLK_DIV 1 +ad_ip_parameter util_daq2_xcvr CONFIG.QPLL_FBDIV_RATIO 1 +ad_ip_parameter util_daq2_xcvr CONFIG.QPLL_FBDIV 0x30; # 20 +ad_ip_parameter util_daq2_xcvr CONFIG.RX_OUT_DIV 1 +ad_ip_parameter util_daq2_xcvr CONFIG.TX_OUT_DIV 1 +ad_ip_parameter util_daq2_xcvr CONFIG.RX_DFE_LPM_CFG 0x0104 +ad_ip_parameter util_daq2_xcvr CONFIG.RX_CDR_CFG 0x0B000023FF10400020 + +ad_connect sys_cpu_resetn util_daq2_xcvr/up_rstn +ad_connect sys_cpu_clk util_daq2_xcvr/up_clk + +# reference clocks & resets + +create_bd_port -dir I tx_ref_clk_0 +create_bd_port -dir I rx_ref_clk_0 + +ad_xcvrpll tx_ref_clk_0 util_daq2_xcvr/qpll_ref_clk_* +ad_xcvrpll rx_ref_clk_0 util_daq2_xcvr/cpll_ref_clk_* +ad_xcvrpll axi_ad9144_xcvr/up_pll_rst util_daq2_xcvr/up_qpll_rst_* +ad_xcvrpll axi_ad9680_xcvr/up_pll_rst util_daq2_xcvr/up_cpll_rst_* + +# connections (dac) + +ad_xcvrcon util_daq2_xcvr axi_ad9144_xcvr axi_ad9144_jesd {0 2 3 1} +ad_connect util_daq2_xcvr/tx_out_clk_0 axi_ad9144_core/tx_clk +ad_connect axi_ad9144_jesd/tx_data_tdata axi_ad9144_core/tx_data +ad_connect util_daq2_xcvr/tx_out_clk_0 axi_ad9144_upack/dac_clk +ad_connect axi_ad9144_core/dac_enable_0 axi_ad9144_upack/dac_enable_0 +ad_connect axi_ad9144_core/dac_ddata_0 axi_ad9144_upack/dac_data_0 +ad_connect axi_ad9144_core/dac_valid_0 axi_ad9144_upack/dac_valid_0 +ad_connect axi_ad9144_core/dac_enable_1 axi_ad9144_upack/dac_enable_1 +ad_connect axi_ad9144_core/dac_ddata_1 axi_ad9144_upack/dac_data_1 +ad_connect axi_ad9144_core/dac_valid_1 axi_ad9144_upack/dac_valid_1 +ad_connect util_daq2_xcvr/tx_out_clk_0 axi_ad9144_fifo/dac_clk +ad_connect axi_ad9144_jesd_rstgen/peripheral_reset axi_ad9144_fifo/dac_rst +ad_connect axi_ad9144_upack/dac_valid axi_ad9144_fifo/dac_valid +ad_connect axi_ad9144_upack/dac_data axi_ad9144_fifo/dac_data +ad_connect axi_ad9144_core/dac_dunf axi_ad9144_fifo/dac_dunf +ad_connect sys_cpu_clk axi_ad9144_fifo/dma_clk +ad_connect sys_cpu_reset axi_ad9144_fifo/dma_rst +ad_connect sys_cpu_clk axi_ad9144_dma/m_axis_aclk +ad_connect sys_cpu_resetn axi_ad9144_dma/m_src_axi_aresetn +ad_connect axi_ad9144_fifo/dma_xfer_req axi_ad9144_dma/m_axis_xfer_req +ad_connect axi_ad9144_fifo/dma_ready axi_ad9144_dma/m_axis_ready +ad_connect axi_ad9144_fifo/dma_data axi_ad9144_dma/m_axis_data +ad_connect axi_ad9144_fifo/dma_valid axi_ad9144_dma/m_axis_valid +ad_connect axi_ad9144_fifo/dma_xfer_last axi_ad9144_dma/m_axis_last + +# connections (adc) + +ad_xcvrcon util_daq2_xcvr axi_ad9680_xcvr axi_ad9680_jesd +ad_connect util_daq2_xcvr/rx_out_clk_0 axi_ad9680_core/rx_clk +ad_connect axi_ad9680_jesd/rx_sof axi_ad9680_core/rx_sof +ad_connect axi_ad9680_jesd/rx_data_tdata axi_ad9680_core/rx_data +ad_connect util_daq2_xcvr/rx_out_clk_0 axi_ad9680_cpack/adc_clk +ad_connect axi_ad9680_jesd_rstgen/peripheral_reset axi_ad9680_cpack/adc_rst +ad_connect axi_ad9680_core/adc_enable_0 axi_ad9680_cpack/adc_enable_0 +ad_connect axi_ad9680_core/adc_valid_0 axi_ad9680_cpack/adc_valid_0 +ad_connect axi_ad9680_core/adc_data_0 axi_ad9680_cpack/adc_data_0 +ad_connect axi_ad9680_core/adc_enable_1 axi_ad9680_cpack/adc_enable_1 +ad_connect axi_ad9680_core/adc_valid_1 axi_ad9680_cpack/adc_valid_1 +ad_connect axi_ad9680_core/adc_data_1 axi_ad9680_cpack/adc_data_1 +ad_connect util_daq2_xcvr/rx_out_clk_0 axi_ad9680_fifo/adc_clk +ad_connect axi_ad9680_jesd_rstgen/peripheral_reset axi_ad9680_fifo/adc_rst +ad_connect axi_ad9680_cpack/adc_valid axi_ad9680_fifo/adc_wr +ad_connect axi_ad9680_cpack/adc_data axi_ad9680_fifo/adc_wdata +ad_connect sys_cpu_clk axi_ad9680_fifo/dma_clk +ad_connect sys_cpu_clk axi_ad9680_dma/s_axis_aclk +ad_connect sys_cpu_resetn axi_ad9680_dma/m_dest_axi_aresetn +ad_connect axi_ad9680_fifo/dma_wr axi_ad9680_dma/s_axis_valid +ad_connect axi_ad9680_fifo/dma_wdata axi_ad9680_dma/s_axis_data +ad_connect axi_ad9680_fifo/dma_wready axi_ad9680_dma/s_axis_ready +ad_connect axi_ad9680_fifo/dma_xfer_req axi_ad9680_dma/s_axis_xfer_req +ad_connect axi_ad9680_core/adc_dovf axi_ad9680_fifo/adc_wovf + +# interconnect (cpu) + +ad_cpu_interconnect 0x44A60000 axi_ad9144_xcvr +ad_cpu_interconnect 0x44A00000 axi_ad9144_core +ad_cpu_interconnect 0x44A90000 axi_ad9144_jesd +ad_cpu_interconnect 0x7c420000 axi_ad9144_dma +ad_cpu_interconnect 0x44A50000 axi_ad9680_xcvr +ad_cpu_interconnect 0x44A10000 axi_ad9680_core +ad_cpu_interconnect 0x44AA0000 axi_ad9680_jesd +ad_cpu_interconnect 0x7c400000 axi_ad9680_dma + +# gt uses hp3, and 100MHz clock for both DRP and AXI4 + +ad_mem_hp3_interconnect sys_cpu_clk sys_ps7/S_AXI_HP3 +ad_mem_hp3_interconnect sys_cpu_clk axi_ad9680_xcvr/m_axi + +# interconnect (mem/dac) + +ad_mem_hp1_interconnect sys_cpu_clk sys_ps7/S_AXI_HP1 +ad_mem_hp1_interconnect sys_cpu_clk axi_ad9144_dma/m_src_axi +ad_mem_hp2_interconnect sys_cpu_clk sys_ps7/S_AXI_HP2 +ad_mem_hp2_interconnect sys_cpu_clk axi_ad9680_dma/m_dest_axi + +# interrupts + +ad_cpu_interrupt ps-10 mb-15 axi_ad9144_jesd/irq +ad_cpu_interrupt ps-11 mb-14 axi_ad9680_jesd/irq +ad_cpu_interrupt ps-12 mb-13 axi_ad9144_dma/irq +ad_cpu_interrupt ps-13 mb-12 axi_ad9680_dma/irq + +ad_connect axi_ad9144_fifo/bypass GND + diff --git a/CI/projects/daq2/common/daq2_qsys.tcl b/CI/projects/daq2/common/daq2_qsys.tcl new file mode 100644 index 00000000..37e411a4 --- /dev/null +++ b/CI/projects/daq2/common/daq2_qsys.tcl @@ -0,0 +1,205 @@ + +# ad9144-xcvr + +add_instance ad9144_jesd204 adi_jesd204 +set_instance_parameter_value ad9144_jesd204 {ID} {0} +set_instance_parameter_value ad9144_jesd204 {TX_OR_RX_N} {1} +set_instance_parameter_value ad9144_jesd204 {LANE_RATE} {10000} +set_instance_parameter_value ad9144_jesd204 {REFCLK_FREQUENCY} {333.333333} +set_instance_parameter_value ad9144_jesd204 {LANE_MAP} {0 3 1 2} +set_instance_parameter_value ad9144_jesd204 {SOFT_PCS} {true} + +add_connection sys_clk.clk ad9144_jesd204.sys_clk +add_connection sys_clk.clk_reset ad9144_jesd204.sys_resetn +add_interface tx_ref_clk clock sink +set_interface_property tx_ref_clk EXPORT_OF ad9144_jesd204.ref_clk +add_interface tx_serial_data conduit end +set_interface_property tx_serial_data EXPORT_OF ad9144_jesd204.serial_data +add_interface tx_sysref conduit end +set_interface_property tx_sysref EXPORT_OF ad9144_jesd204.sysref +add_interface tx_sync conduit end +set_interface_property tx_sync EXPORT_OF ad9144_jesd204.sync + +# ad9144-core + +add_instance axi_ad9144_core axi_ad9144 +set_instance_parameter_value axi_ad9144_core {QUAD_OR_DUAL_N} {0} + +add_connection ad9144_jesd204.link_clk axi_ad9144_core.if_tx_clk +add_connection axi_ad9144_core.if_tx_data ad9144_jesd204.link_data +add_connection sys_clk.clk_reset axi_ad9144_core.s_axi_reset +add_connection sys_clk.clk axi_ad9144_core.s_axi_clock + +# ad9144-unpack + +add_instance util_ad9144_upack util_upack +set_instance_parameter_value util_ad9144_upack {CHANNEL_DATA_WIDTH} {64} +set_instance_parameter_value util_ad9144_upack {NUM_OF_CHANNELS} {2} + +add_connection ad9144_jesd204.link_clk util_ad9144_upack.if_dac_clk +add_connection axi_ad9144_core.dac_ch_0 util_ad9144_upack.dac_ch_0 +add_connection axi_ad9144_core.dac_ch_1 util_ad9144_upack.dac_ch_1 + +# dac fifo + +add_interface tx_fifo_bypass conduit end +set_interface_property tx_fifo_bypass EXPORT_OF avl_ad9144_fifo.if_bypass + +add_connection ad9144_jesd204.link_clk avl_ad9144_fifo.if_dac_clk +add_connection ad9144_jesd204.link_reset avl_ad9144_fifo.if_dac_rst +add_connection util_ad9144_upack.if_dac_valid avl_ad9144_fifo.if_dac_valid +add_connection avl_ad9144_fifo.if_dac_data util_ad9144_upack.if_dac_data +add_connection avl_ad9144_fifo.if_dac_dunf axi_ad9144_core.if_dac_dunf + +# ad9144-dma + +add_instance axi_ad9144_dma axi_dmac +set_instance_parameter_value axi_ad9144_dma {DMA_DATA_WIDTH_SRC} {128} +set_instance_parameter_value axi_ad9144_dma {DMA_DATA_WIDTH_DEST} {128} +set_instance_parameter_value axi_ad9144_dma {DMA_2D_TRANSFER} {0} +set_instance_parameter_value axi_ad9144_dma {DMA_LENGTH_WIDTH} {24} +set_instance_parameter_value axi_ad9144_dma {AXI_SLICE_DEST} {0} +set_instance_parameter_value axi_ad9144_dma {AXI_SLICE_SRC} {0} +set_instance_parameter_value axi_ad9144_dma {SYNC_TRANSFER_START} {0} +set_instance_parameter_value axi_ad9144_dma {CYCLIC} {1} +set_instance_parameter_value axi_ad9144_dma {DMA_TYPE_DEST} {1} +set_instance_parameter_value axi_ad9144_dma {DMA_TYPE_SRC} {0} +set_instance_parameter_value axi_ad9144_dma {FIFO_SIZE} {16} +set_instance_parameter_value axi_ad9144_dma {USE_TLAST_DEST} {1} + +add_connection sys_dma_clk.clk avl_ad9144_fifo.if_dma_clk +add_connection sys_dma_clk.clk_reset avl_ad9144_fifo.if_dma_rst +add_connection sys_dma_clk.clk axi_ad9144_dma.if_m_axis_aclk +add_connection axi_ad9144_dma.if_m_axis_valid avl_ad9144_fifo.if_dma_valid +add_connection axi_ad9144_dma.if_m_axis_data avl_ad9144_fifo.if_dma_data +add_connection axi_ad9144_dma.if_m_axis_last avl_ad9144_fifo.if_dma_xfer_last +add_connection axi_ad9144_dma.if_m_axis_xfer_req avl_ad9144_fifo.if_dma_xfer_req +add_connection avl_ad9144_fifo.if_dma_ready axi_ad9144_dma.if_m_axis_ready +add_connection sys_clk.clk_reset axi_ad9144_dma.s_axi_reset +add_connection sys_clk.clk axi_ad9144_dma.s_axi_clock +add_connection sys_dma_clk.clk_reset axi_ad9144_dma.m_src_axi_reset +add_connection sys_dma_clk.clk axi_ad9144_dma.m_src_axi_clock + +# ad9680-xcvr + +add_instance ad9680_jesd204 adi_jesd204 +set_instance_parameter_value ad9680_jesd204 {ID} {1} +set_instance_parameter_value ad9680_jesd204 {TX_OR_RX_N} {0} +set_instance_parameter_value ad9680_jesd204 {LANE_RATE} {10000.0} +set_instance_parameter_value ad9680_jesd204 {REFCLK_FREQUENCY} {333.333333} +set_instance_parameter_value ad9680_jesd204 {NUM_OF_LANES} {4} +set_instance_parameter_value ad9680_jesd204 {SOFT_PCS} {true} + +add_connection sys_clk.clk ad9680_jesd204.sys_clk +add_connection sys_clk.clk_reset ad9680_jesd204.sys_resetn +add_interface rx_ref_clk clock sink +set_interface_property rx_ref_clk EXPORT_OF ad9680_jesd204.ref_clk +add_interface rx_serial_data conduit end +set_interface_property rx_serial_data EXPORT_OF ad9680_jesd204.serial_data +add_interface rx_sysref conduit end +set_interface_property rx_sysref EXPORT_OF ad9680_jesd204.sysref +add_interface rx_sync conduit end +set_interface_property rx_sync EXPORT_OF ad9680_jesd204.sync + +# ad9680 + +add_instance axi_ad9680_core axi_ad9680 + +add_connection ad9680_jesd204.link_clk axi_ad9680_core.if_rx_clk +add_connection ad9680_jesd204.link_sof axi_ad9680_core.if_rx_sof +add_connection ad9680_jesd204.link_data axi_ad9680_core.if_rx_data +add_connection sys_clk.clk_reset axi_ad9680_core.s_axi_reset +add_connection sys_clk.clk axi_ad9680_core.s_axi_clock + +# ad9680-pack + +add_instance util_ad9680_cpack util_cpack +set_instance_parameter_value util_ad9680_cpack {CHANNEL_DATA_WIDTH} {64} +set_instance_parameter_value util_ad9680_cpack {NUM_OF_CHANNELS} {2} + +add_connection sys_clk.clk_reset util_ad9680_cpack.if_adc_rst +add_connection ad9680_jesd204.link_clk util_ad9680_cpack.if_adc_clk +add_connection axi_ad9680_core.adc_ch_0 util_ad9680_cpack.adc_ch_0 +add_connection axi_ad9680_core.adc_ch_1 util_ad9680_cpack.adc_ch_1 + +# ad9680-fifo + +add_instance ad9680_adcfifo util_adcfifo +set_instance_parameter_value ad9680_adcfifo {ADC_DATA_WIDTH} {128} +set_instance_parameter_value ad9680_adcfifo {DMA_DATA_WIDTH} {128} +set_instance_parameter_value ad9680_adcfifo {DMA_ADDRESS_WIDTH} {16} + +add_connection sys_clk.clk_reset ad9680_adcfifo.if_adc_rst +add_connection ad9680_jesd204.link_clk ad9680_adcfifo.if_adc_clk +add_connection util_ad9680_cpack.if_adc_valid ad9680_adcfifo.if_adc_wr +add_connection util_ad9680_cpack.if_adc_data ad9680_adcfifo.if_adc_wdata +add_connection sys_dma_clk.clk ad9680_adcfifo.if_dma_clk +add_connection sys_dma_clk.clk_reset ad9680_adcfifo.if_adc_rst + +# ad9680-dma + +add_instance axi_ad9680_dma axi_dmac +set_instance_parameter_value axi_ad9680_dma {DMA_DATA_WIDTH_SRC} {128} +set_instance_parameter_value axi_ad9680_dma {DMA_DATA_WIDTH_DEST} {128} +set_instance_parameter_value axi_ad9680_dma {DMA_LENGTH_WIDTH} {24} +set_instance_parameter_value axi_ad9680_dma {DMA_2D_TRANSFER} {0} +set_instance_parameter_value axi_ad9680_dma {SYNC_TRANSFER_START} {0} +set_instance_parameter_value axi_ad9680_dma {CYCLIC} {0} +set_instance_parameter_value axi_ad9680_dma {DMA_TYPE_DEST} {0} +set_instance_parameter_value axi_ad9680_dma {DMA_TYPE_SRC} {1} + +add_connection sys_dma_clk.clk axi_ad9680_dma.if_s_axis_aclk +add_connection ad9680_adcfifo.if_dma_wr axi_ad9680_dma.if_s_axis_valid +add_connection ad9680_adcfifo.if_dma_wdata axi_ad9680_dma.if_s_axis_data +add_connection ad9680_adcfifo.if_dma_wready axi_ad9680_dma.if_s_axis_ready +add_connection ad9680_adcfifo.if_dma_xfer_req axi_ad9680_dma.if_s_axis_xfer_req +add_connection ad9680_adcfifo.if_adc_wovf axi_ad9680_core.if_adc_dovf +add_connection sys_clk.clk_reset axi_ad9680_dma.s_axi_reset +add_connection sys_clk.clk axi_ad9680_dma.s_axi_clock +add_connection sys_dma_clk.clk_reset axi_ad9680_dma.m_dest_axi_reset +add_connection sys_dma_clk.clk axi_ad9680_dma.m_dest_axi_clock + +# reconfig sharing + +for {set i 0} {$i < 4} {incr i} { + add_instance avl_adxcfg_${i} avl_adxcfg + add_connection sys_clk.clk avl_adxcfg_${i}.rcfg_clk + add_connection sys_clk.clk_reset avl_adxcfg_${i}.rcfg_reset_n + add_connection avl_adxcfg_${i}.rcfg_m0 ad9144_jesd204.phy_reconfig_${i} + add_connection avl_adxcfg_${i}.rcfg_m1 ad9680_jesd204.phy_reconfig_${i} +} + +# addresses + +ad_cpu_interconnect 0x00020000 ad9144_jesd204.link_reconfig +ad_cpu_interconnect 0x00024000 ad9144_jesd204.link_management +ad_cpu_interconnect 0x00025000 ad9144_jesd204.link_pll_reconfig +ad_cpu_interconnect 0x00026000 ad9144_jesd204.lane_pll_reconfig +ad_cpu_interconnect 0x00028000 avl_adxcfg_0.rcfg_s0 +ad_cpu_interconnect 0x00029000 avl_adxcfg_1.rcfg_s0 +ad_cpu_interconnect 0x0002a000 avl_adxcfg_2.rcfg_s0 +ad_cpu_interconnect 0x0002b000 avl_adxcfg_3.rcfg_s0 +ad_cpu_interconnect 0x0002c000 axi_ad9144_dma.s_axi +ad_cpu_interconnect 0x00030000 axi_ad9144_core.s_axi + +ad_cpu_interconnect 0x00040000 ad9680_jesd204.link_reconfig +ad_cpu_interconnect 0x00044000 ad9680_jesd204.link_management +ad_cpu_interconnect 0x00045000 ad9680_jesd204.link_pll_reconfig +ad_cpu_interconnect 0x00048000 avl_adxcfg_0.rcfg_s1 +ad_cpu_interconnect 0x00049000 avl_adxcfg_1.rcfg_s1 +ad_cpu_interconnect 0x0004a000 avl_adxcfg_2.rcfg_s1 +ad_cpu_interconnect 0x0004b000 avl_adxcfg_3.rcfg_s1 +ad_cpu_interconnect 0x0004c000 axi_ad9680_dma.s_axi +ad_cpu_interconnect 0x00050000 axi_ad9680_core.s_axi + +# dma interconnects + +ad_dma_interconnect axi_ad9144_dma.m_src_axi +ad_dma_interconnect axi_ad9680_dma.m_dest_axi + +# interrupts + +ad_cpu_interrupt 8 ad9680_jesd204.interrupt +ad_cpu_interrupt 9 ad9144_jesd204.interrupt +ad_cpu_interrupt 10 axi_ad9680_dma.interrupt_sender +ad_cpu_interrupt 11 axi_ad9144_dma.interrupt_sender diff --git a/CI/projects/daq2/common/daq2_spi.v b/CI/projects/daq2/common/daq2_spi.v new file mode 100644 index 00000000..c9f09ed0 --- /dev/null +++ b/CI/projects/daq2/common/daq2_spi.v @@ -0,0 +1,95 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module daq2_spi ( + + input [ 2:0] spi_csn, + input spi_clk, + input spi_mosi, + output spi_miso, + + inout spi_sdio, + output spi_dir); + + // internal registers + + reg [ 5:0] spi_count = 'd0; + reg spi_rd_wr_n = 'd0; + reg spi_enable = 'd0; + + // internal signals + + wire spi_csn_s; + wire spi_enable_s; + + // check on rising edge and change on falling edge + + assign spi_csn_s = & spi_csn; + assign spi_dir = ~spi_enable_s; + assign spi_enable_s = spi_enable & ~spi_csn_s; + + always @(posedge spi_clk or posedge spi_csn_s) begin + if (spi_csn_s == 1'b1) begin + spi_count <= 6'd0; + spi_rd_wr_n <= 1'd0; + end else begin + spi_count <= (spi_count < 6'h3f) ? spi_count + 1'b1 : spi_count; + if (spi_count == 6'd0) begin + spi_rd_wr_n <= spi_mosi; + end + end + end + + always @(negedge spi_clk or posedge spi_csn_s) begin + if (spi_csn_s == 1'b1) begin + spi_enable <= 1'b0; + end else begin + if (spi_count == 6'd16) begin + spi_enable <= spi_rd_wr_n; + end + end + end + + // io butter + + assign spi_miso = spi_sdio; + assign spi_sdio = (spi_enable_s == 1'b1) ? 1'bz : spi_mosi; + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/CI/projects/daq2/zcu102/Makefile b/CI/projects/daq2/zcu102/Makefile new file mode 100644 index 00000000..fc83d383 --- /dev/null +++ b/CI/projects/daq2/zcu102/Makefile @@ -0,0 +1,31 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +PROJECT_NAME := daq2_zcu102 + +M_DEPS += ../common/daq2_spi.v +M_DEPS += ../common/daq2_bd.tcl +M_DEPS += ../../common/zcu102/zcu102_system_constr.xdc +M_DEPS += ../../common/zcu102/zcu102_system_bd.tcl +M_DEPS += ../../common/xilinx/dacfifo_bd.tcl +M_DEPS += ../../common/xilinx/adcfifo_bd.tcl +M_DEPS += ../../../library/xilinx/common/ad_iobuf.v +M_DEPS += ../../../library/jesd204/scripts/jesd204.tcl + +LIB_DEPS += axi_ad9144 +LIB_DEPS += axi_ad9680 +LIB_DEPS += axi_dmac +LIB_DEPS += jesd204/axi_jesd204_rx +LIB_DEPS += jesd204/axi_jesd204_tx +LIB_DEPS += jesd204/jesd204_rx +LIB_DEPS += jesd204/jesd204_tx +LIB_DEPS += util_adcfifo +LIB_DEPS += util_cpack +LIB_DEPS += util_dacfifo +LIB_DEPS += util_upack +LIB_DEPS += xilinx/axi_adxcvr +LIB_DEPS += xilinx/util_adxcvr + +include ../../scripts/project-xilinx.mk diff --git a/CI/projects/daq2/zcu102/boot/bl31.elf b/CI/projects/daq2/zcu102/boot/bl31.elf new file mode 100644 index 00000000..7e8295a9 Binary files /dev/null and b/CI/projects/daq2/zcu102/boot/bl31.elf differ diff --git a/CI/projects/daq2/zcu102/boot/fsbl.elf b/CI/projects/daq2/zcu102/boot/fsbl.elf new file mode 100755 index 00000000..2357b264 Binary files /dev/null and b/CI/projects/daq2/zcu102/boot/fsbl.elf differ diff --git a/CI/projects/daq2/zcu102/boot/pmufw.elf b/CI/projects/daq2/zcu102/boot/pmufw.elf new file mode 100755 index 00000000..b4ff0452 Binary files /dev/null and b/CI/projects/daq2/zcu102/boot/pmufw.elf differ diff --git a/CI/projects/daq2/zcu102/boot/u-boot-zcu.elf b/CI/projects/daq2/zcu102/boot/u-boot-zcu.elf new file mode 100644 index 00000000..d4edf69c Binary files /dev/null and b/CI/projects/daq2/zcu102/boot/u-boot-zcu.elf differ diff --git a/CI/projects/daq2/zcu102/boot/uEnv.txt b/CI/projects/daq2/zcu102/boot/uEnv.txt new file mode 100644 index 00000000..90654b03 --- /dev/null +++ b/CI/projects/daq2/zcu102/boot/uEnv.txt @@ -0,0 +1,5 @@ +uenvcmd=run adi_sdboot +adi_sdboot=echo Copying Linux from SD to RAM... && fatload mmc 0 0x3000000 ${kernel_image} && fatload mmc 0 0x2A00000 ${devicetree_image} && if fatload mmc 0 0x2000000 ${ramdisk_image}; then bootm 0x3000000 0x2000000 0x2A00000; else bootm 0x3000000 - 0x2A00000; fi +bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait + + diff --git a/CI/projects/daq2/zcu102/boot/zynqmp.bif b/CI/projects/daq2/zcu102/boot/zynqmp.bif new file mode 100644 index 00000000..a86aa22f --- /dev/null +++ b/CI/projects/daq2/zcu102/boot/zynqmp.bif @@ -0,0 +1,8 @@ +the_ROM_image: +{ +[pmufw_image] ./pmufw.elf +[bootloader,destination_cpu=a53-0] ./fsbl.elf +[destination_device=pl] ./system_top.bit +[destination_cpu=a53-0,exception_level=el-3,trustzone] ./bl31.elf +[destination_cpu=a53-0,exception_level=el-2] ./u-boot-zcu.elf +} diff --git a/CI/projects/daq2/zcu102/config_prj.tcl b/CI/projects/daq2/zcu102/config_prj.tcl new file mode 100644 index 00000000..5ba9c352 --- /dev/null +++ b/CI/projects/daq2/zcu102/config_prj.tcl @@ -0,0 +1,11 @@ +global ref_design + +# Add 1 extra AXI master ports to the interconnect +set_property -dict [list CONFIG.NUM_MI {9}] [get_bd_cells axi_cpu_interconnect] + +if {$ref_design eq "Rx" || $ref_design eq "Rx & Tx"} { + connect_bd_net [get_bd_pins axi_cpu_interconnect/M08_ARESETN] [get_bd_pins axi_ad9680_jesd_rstgen/interconnect_aresetn] +} +if {$ref_design eq "Tx"} { + connect_bd_net [get_bd_pins axi_cpu_interconnect/M08_ARESETN] [get_bd_pins axi_ad9144_jesd_rstgen/interconnect_aresetn] +} \ No newline at end of file diff --git a/CI/projects/daq2/zcu102/config_rxtx.tcl b/CI/projects/daq2/zcu102/config_rxtx.tcl new file mode 100644 index 00000000..e8759da1 --- /dev/null +++ b/CI/projects/daq2/zcu102/config_rxtx.tcl @@ -0,0 +1,7 @@ +set ad_hdl_dir [pwd] +set proj_dir $ad_hdl_dir/projects/daq2/zcu102 + +source $proj_dir/config_prj.tcl +source $ad_hdl_dir/projects/daq2/common/config_rxtx.tcl + +regenerate_bd_layout \ No newline at end of file diff --git a/CI/projects/daq2/zcu102/system_bd.tcl b/CI/projects/daq2/zcu102/system_bd.tcl new file mode 100644 index 00000000..0c70e449 --- /dev/null +++ b/CI/projects/daq2/zcu102/system_bd.tcl @@ -0,0 +1,27 @@ + +## FIFO depth is 8Mb - 500k samples +set adc_fifo_name axi_ad9680_fifo +set adc_fifo_address_width 17 +set adc_data_width 128 +set adc_dma_data_width 64 + +## FIFO depth is 8Mb - 500k samples +set dac_fifo_name axi_ad9144_fifo +set dac_fifo_address_width 16 +set dac_data_width 128 +set dac_dma_data_width 128 + +## NOTE: With this configuration the #36Kb BRAM utilization is at ~57% + +source $ad_hdl_dir/projects/common/zcu102/zcu102_system_bd.tcl +source $ad_hdl_dir/projects/common/xilinx/adcfifo_bd.tcl +source $ad_hdl_dir/projects/common/xilinx/dacfifo_bd.tcl +source $ad_hdl_dir/projects/daq2/common/daq2_bd.tcl + +ad_ip_parameter axi_ad9144_xcvr CONFIG.XCVR_TYPE 2 +ad_ip_parameter axi_ad9680_xcvr CONFIG.XCVR_TYPE 2 + +ad_ip_parameter util_daq2_xcvr CONFIG.XCVR_TYPE 2 +ad_ip_parameter util_daq2_xcvr CONFIG.QPLL_FBDIV 20 +ad_ip_parameter util_daq2_xcvr CONFIG.QPLL_REFCLK_DIV 1 + diff --git a/CI/projects/daq2/zcu102/system_constr.xdc b/CI/projects/daq2/zcu102/system_constr.xdc new file mode 100644 index 00000000..d6a5d001 --- /dev/null +++ b/CI/projects/daq2/zcu102/system_constr.xdc @@ -0,0 +1,73 @@ + +# daq2 + +set_property -dict {PACKAGE_PIN AB4 IOSTANDARD LVDS} [get_ports rx_sync_p] ; ## D08 FMC_HPC0_LA01_CC_P +set_property -dict {PACKAGE_PIN AC4 IOSTANDARD LVDS} [get_ports rx_sync_n] ; ## D09 FMC_HPC0_LA01_CC_N +set_property -dict {PACKAGE_PIN Y2 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports rx_sysref_p] ; ## G09 FMC_HPC0_LA03_P +set_property -dict {PACKAGE_PIN Y1 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports rx_sysref_n] ; ## G10 FMC_HPC0_LA03_N +set_property -dict {PACKAGE_PIN V2 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports tx_sync_p] ; ## H07 FMC_HPC0_LA02_P +set_property -dict {PACKAGE_PIN V1 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports tx_sync_n] ; ## H08 FMC_HPC0_LA02_N +set_property -dict {PACKAGE_PIN AA2 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports tx_sysref_p] ; ## H10 FMC_HPC0_LA04_P +set_property -dict {PACKAGE_PIN AA1 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports tx_sysref_n] ; ## H11 FMC_HPC0_LA04_N + +set_property -dict {PACKAGE_PIN AB3 IOSTANDARD LVCMOS18} [get_ports spi_csn_clk] ; ## D11 FMC_HPC0_LA05_P +set_property -dict {PACKAGE_PIN W5 IOSTANDARD LVCMOS18} [get_ports spi_csn_dac] ; ## C14 FMC_HPC0_LA10_P +set_property -dict {PACKAGE_PIN W1 IOSTANDARD LVCMOS18} [get_ports spi_csn_adc] ; ## D15 FMC_HPC0_LA09_N +set_property -dict {PACKAGE_PIN AC3 IOSTANDARD LVCMOS18} [get_ports spi_clk] ; ## D12 FMC_HPC0_LA05_N +set_property -dict {PACKAGE_PIN W2 IOSTANDARD LVCMOS18} [get_ports spi_sdio] ; ## D14 FMC_HPC0_LA09_P +set_property -dict {PACKAGE_PIN V3 IOSTANDARD LVCMOS18} [get_ports spi_dir] ; ## G13 FMC_HPC0_LA08_N + +set_property -dict {PACKAGE_PIN V4 IOSTANDARD LVCMOS18} [get_ports clkd_sync] ; ## G12 FMC_HPC0_LA08_P +set_property -dict {PACKAGE_PIN W4 IOSTANDARD LVCMOS18} [get_ports dac_reset] ; ## C15 FMC_HPC0_LA10_N +set_property -dict {PACKAGE_PIN W6 IOSTANDARD LVCMOS18} [get_ports dac_txen] ; ## G16 FMC_HPC0_LA12_N +set_property -dict {PACKAGE_PIN AC2 IOSTANDARD LVCMOS18} [get_ports adc_pd] ; ## C10 FMC_HPC0_LA06_P + +set_property -dict {PACKAGE_PIN AB8 IOSTANDARD LVCMOS18} [get_ports clkd_status[0]] ; ## D17 FMC_HPC0_LA13_P +set_property -dict {PACKAGE_PIN AC8 IOSTANDARD LVCMOS18} [get_ports clkd_status[1]] ; ## D18 FMC_HPC0_LA13_N +set_property -dict {PACKAGE_PIN W7 IOSTANDARD LVCMOS18} [get_ports dac_irq] ; ## G15 FMC_HPC0_LA12_P +set_property -dict {PACKAGE_PIN AB6 IOSTANDARD LVCMOS18} [get_ports adc_fda] ; ## H16 FMC_HPC0_LA11_P +set_property -dict {PACKAGE_PIN AB5 IOSTANDARD LVCMOS18} [get_ports adc_fdb] ; ## H17 FMC_HPC0_LA11_N + +set_property -dict {PACKAGE_PIN U5 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports trig_p] ; ## H13 FMC_HPC0_LA07_P +set_property -dict {PACKAGE_PIN U4 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports trig_n] ; ## H14 FMC_HPC0_LA07_N + +set_property LOC GTHE4_COMMON_X1Y1 [get_cells -hierarchical -filter {NAME =~ *i_ibufds_rx_ref_clk}] +set_property LOC GTHE4_COMMON_X1Y2 [get_cells -hierarchical -filter {NAME =~ *i_ibufds_tx_ref_clk}] + +# clocks + +create_clock -name tx_ref_clk -period 2.00 [get_ports tx_ref_clk_p] +create_clock -name rx_ref_clk -period 2.00 [get_ports rx_ref_clk_p] +create_clock -name tx_div_clk -period 4.00 [get_pins i_system_wrapper/system_i/util_daq2_xcvr/inst/i_xch_0/i_gthe4_channel/TXOUTCLK] +create_clock -name rx_div_clk -period 4.00 [get_pins i_system_wrapper/system_i/util_daq2_xcvr/inst/i_xch_0/i_gthe4_channel/RXOUTCLK] + +# pin assignments below are for reference only and are ignored by the tool! + +## set_property -dict {PACKAGE_PIN L8} [get_ports rx_ref_clk_p] ; ## B20 FMC_HPC0_GBTCLK1_M2C_P +## set_property -dict {PACKAGE_PIN L7} [get_ports rx_ref_clk_n] ; ## B21 FMC_HPC0_GBTCLK1_M2C_N +## set_property -dict {PACKAGE_PIN G8} [get_ports tx_ref_clk_p] ; ## D04 FMC_HPC0_GBTCLK0_M2C_P +## set_property -dict {PACKAGE_PIN G7} [get_ports tx_ref_clk_n] ; ## D05 FMC_HPC0_GBTCLK0_M2C_N + +## set_property -dict {PACKAGE_PIN K2} [get_ports rx_data_p[0]] ; ## A10 FMC_HPC0_DP3_M2C_P +## set_property -dict {PACKAGE_PIN K1} [get_ports rx_data_n[0]] ; ## A11 FMC_HPC0_DP3_M2C_N +## set_property -dict {PACKAGE_PIN H2} [get_ports rx_data_p[1]] ; ## C06 FMC_HPC0_DP0_M2C_P +## set_property -dict {PACKAGE_PIN H1} [get_ports rx_data_n[1]] ; ## C07 FMC_HPC0_DP0_M2C_N +## set_property -dict {PACKAGE_PIN F2} [get_ports rx_data_p[2]] ; ## A06 FMC_HPC0_DP2_M2C_P +## set_property -dict {PACKAGE_PIN F1} [get_ports rx_data_n[2]] ; ## A07 FMC_HPC0_DP2_M2C_N +## set_property -dict {PACKAGE_PIN J4} [get_ports rx_data_p[3]] ; ## A02 FMC_HPC0_DP1_M2C_P +## set_property -dict {PACKAGE_PIN J3} [get_ports rx_data_n[3]] ; ## A03 FMC_HPC0_DP1_M2C_N +## set_property -dict {PACKAGE_PIN K6} [get_ports tx_data_p[0]] ; ## A30 FMC_HPC0_DP3_C2M_P (tx_data_p[0]) +## set_property -dict {PACKAGE_PIN K5} [get_ports tx_data_n[0]] ; ## A31 FMC_HPC0_DP3_C2M_N (tx_data_n[0]) +## set_property -dict {PACKAGE_PIN G4} [get_ports tx_data_p[1]] ; ## C02 FMC_HPC0_DP0_C2M_P (tx_data_p[3]) +## set_property -dict {PACKAGE_PIN G3} [get_ports tx_data_n[1]] ; ## C03 FMC_HPC0_DP0_C2M_N (tx_data_n[3]) +## set_property -dict {PACKAGE_PIN F6} [get_ports tx_data_p[2]] ; ## A26 FMC_HPC0_DP2_C2M_P (tx_data_p[1]) +## set_property -dict {PACKAGE_PIN F5} [get_ports tx_data_n[2]] ; ## A27 FMC_HPC0_DP2_C2M_N (tx_data_n[1]) +## set_property -dict {PACKAGE_PIN H6} [get_ports tx_data_p[3]] ; ## A22 FMC_HPC0_DP1_C2M_P (tx_data_p[2]) +## set_property -dict {PACKAGE_PIN H5} [get_ports tx_data_n[3]] ; ## A23 FMC_HPC0_DP1_C2M_N (tx_data_n[2]) + +set_property LOC GTHE4_CHANNEL_X1Y8 [get_cells -hierarchical -filter {NAME =~ *util_daq2_xcvr/inst/i_xch_0/i_gthe4_channel}] +set_property LOC GTHE4_CHANNEL_X1Y10 [get_cells -hierarchical -filter {NAME =~ *util_daq2_xcvr/inst/i_xch_1/i_gthe4_channel}] +set_property LOC GTHE4_CHANNEL_X1Y11 [get_cells -hierarchical -filter {NAME =~ *util_daq2_xcvr/inst/i_xch_2/i_gthe4_channel}] +set_property LOC GTHE4_CHANNEL_X1Y9 [get_cells -hierarchical -filter {NAME =~ *util_daq2_xcvr/inst/i_xch_3/i_gthe4_channel}] + + diff --git a/CI/projects/daq2/zcu102/system_project.tcl b/CI/projects/daq2/zcu102/system_project.tcl new file mode 100644 index 00000000..dbcea91d --- /dev/null +++ b/CI/projects/daq2/zcu102/system_project.tcl @@ -0,0 +1,16 @@ + +source ../../scripts/adi_env.tcl +source $ad_hdl_dir/projects/scripts/adi_project.tcl +source $ad_hdl_dir/projects/scripts/adi_board.tcl + +adi_project_xilinx daq2_zcu102 +adi_project_files daq2_zcu102 [list \ + "$ad_hdl_dir/projects/daq2/common/daq2_spi.v" \ + "system_top.v" \ + "system_constr.xdc"\ + "$ad_hdl_dir/library/xilinx/common/ad_iobuf.v" \ + "$ad_hdl_dir/projects/common/zcu102/zcu102_system_constr.xdc" ] + +adi_project_run daq2_zcu102 + + diff --git a/CI/projects/daq2/zcu102/system_project_rxtx.tcl b/CI/projects/daq2/zcu102/system_project_rxtx.tcl new file mode 100644 index 00000000..2fb41bd6 --- /dev/null +++ b/CI/projects/daq2/zcu102/system_project_rxtx.tcl @@ -0,0 +1,19 @@ +set ad_hdl_dir [pwd] +set ad_phdl_dir [pwd] +set proj_dir $ad_hdl_dir/projects/daq2/zcu102 + +source $ad_hdl_dir/projects/scripts/adi_project.tcl +source $ad_hdl_dir/projects/scripts/adi_board.tcl + +adi_project_xilinx daq2_zcu102 $proj_dir config_rxtx.tcl +adi_project_files daq2_zcu102 [list \ + "$ad_hdl_dir/projects/daq2/common/daq2_spi.v" \ + "system_top.v" \ + "system_constr.xdc"\ + "$ad_hdl_dir/library/xilinx/common/ad_iobuf.v" \ + "$ad_hdl_dir/projects/common/zcu102/zcu102_system_constr.xdc" ] + +adi_project_run daq2_zcu102 + +# Copy the boot file to the root directory +file copy -force $proj_dir/boot $ad_hdl_dir/boot \ No newline at end of file diff --git a/CI/projects/daq2/zcu102/system_top.v b/CI/projects/daq2/zcu102/system_top.v new file mode 100644 index 00000000..f8e16160 --- /dev/null +++ b/CI/projects/daq2/zcu102/system_top.v @@ -0,0 +1,206 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module system_top ( + + input [12:0] gpio_bd_i, + output [ 7:0] gpio_bd_o, + + input rx_ref_clk_p, + input rx_ref_clk_n, + input rx_sysref_p, + input rx_sysref_n, + output rx_sync_p, + output rx_sync_n, + input [ 3:0] rx_data_p, + input [ 3:0] rx_data_n, + + input tx_ref_clk_p, + input tx_ref_clk_n, + input tx_sysref_p, + input tx_sysref_n, + input tx_sync_p, + input tx_sync_n, + output [ 3:0] tx_data_p, + output [ 3:0] tx_data_n, + + input trig_p, + input trig_n, + + input adc_fdb, + input adc_fda, + input dac_irq, + input [ 1:0] clkd_status, + + output adc_pd, + output dac_txen, + output dac_reset, + output clkd_sync, + + output spi_csn_clk, + output spi_csn_dac, + output spi_csn_adc, + output spi_clk, + inout spi_sdio, + output spi_dir); + + // internal signals + + wire [94:0] gpio_i; + wire [94:0] gpio_o; + wire [ 2:0] spi_csn; + wire spi_mosi; + wire spi_miso; + wire trig; + wire rx_ref_clk; + wire rx_sysref; + wire rx_sync; + wire tx_ref_clk; + wire tx_sysref; + wire tx_sync; + + // spi + + assign spi_csn_adc = spi_csn[2]; + assign spi_csn_dac = spi_csn[1]; + assign spi_csn_clk = spi_csn[0]; + + // instantiations + + IBUFDS_GTE4 i_ibufds_rx_ref_clk ( + .CEB (1'd0), + .I (rx_ref_clk_p), + .IB (rx_ref_clk_n), + .O (rx_ref_clk), + .ODIV2 ()); + + IBUFDS i_ibufds_rx_sysref ( + .I (rx_sysref_p), + .IB (rx_sysref_n), + .O (rx_sysref)); + + OBUFDS i_obufds_rx_sync ( + .I (rx_sync), + .O (rx_sync_p), + .OB (rx_sync_n)); + + IBUFDS_GTE4 i_ibufds_tx_ref_clk ( + .CEB (1'd0), + .I (tx_ref_clk_p), + .IB (tx_ref_clk_n), + .O (tx_ref_clk), + .ODIV2 ()); + + IBUFDS i_ibufds_tx_sysref ( + .I (tx_sysref_p), + .IB (tx_sysref_n), + .O (tx_sysref)); + + IBUFDS i_ibufds_tx_sync ( + .I (tx_sync_p), + .IB (tx_sync_n), + .O (tx_sync)); + + daq2_spi i_spi ( + .spi_csn (spi_csn), + .spi_clk (spi_clk), + .spi_mosi (spi_mosi), + .spi_miso (spi_miso), + .spi_sdio (spi_sdio), + .spi_dir (spi_dir)); + + IBUFDS i_ibufds_trig ( + .I (trig_p), + .IB (trig_n), + .O (trig)); + + assign adc_pd = gpio_o[42]; + assign dac_txen = gpio_o[41]; + assign dac_reset = gpio_o[40]; + assign clkd_sync = gpio_o[38]; + assign gpio_bd_o = gpio_o[7:0]; + + assign gpio_i[94:44] = gpio_o[94:44]; + assign gpio_i[43:43] = trig; + assign gpio_i[42:37] = gpio_o[42:37]; + assign gpio_i[36:36] = adc_fdb; + assign gpio_i[35:35] = adc_fda; + assign gpio_i[34:34] = dac_irq; + assign gpio_i[33:32] = clkd_status; + assign gpio_i[31:21] = gpio_o[31:21]; + assign gpio_i[20: 8] = gpio_bd_i; + assign gpio_i[ 7: 0] = gpio_o[ 7: 0]; + + system_wrapper i_system_wrapper ( + .gpio_i (gpio_i), + .gpio_o (gpio_o), + .gpio_t (), + .rx_data_0_n (rx_data_n[0]), + .rx_data_0_p (rx_data_p[0]), + .rx_data_1_n (rx_data_n[1]), + .rx_data_1_p (rx_data_p[1]), + .rx_data_2_n (rx_data_n[2]), + .rx_data_2_p (rx_data_p[2]), + .rx_data_3_n (rx_data_n[3]), + .rx_data_3_p (rx_data_p[3]), + .rx_ref_clk_0 (rx_ref_clk), + .rx_sync_0 (rx_sync), + .rx_sysref_0 (rx_sysref), + .spi0_csn (spi_csn), + .spi0_miso (spi_miso), + .spi0_mosi (spi_mosi), + .spi0_sclk (spi_clk), + .spi1_csn (), + .spi1_miso (1'd0), + .spi1_mosi (), + .spi1_sclk (), + .tx_data_0_n (tx_data_n[0]), + .tx_data_0_p (tx_data_p[0]), + .tx_data_1_n (tx_data_n[1]), + .tx_data_1_p (tx_data_p[1]), + .tx_data_2_n (tx_data_n[2]), + .tx_data_2_p (tx_data_p[2]), + .tx_data_3_n (tx_data_n[3]), + .tx_data_3_p (tx_data_p[3]), + .tx_ref_clk_0 (tx_ref_clk), + .tx_sync_0 (tx_sync), + .tx_sysref_0 (tx_sysref)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/CI/projects/scripts/adi_board.tcl b/CI/projects/scripts/adi_board.tcl new file mode 100644 index 00000000..30c9f861 --- /dev/null +++ b/CI/projects/scripts/adi_board.tcl @@ -0,0 +1,731 @@ +################################################################################################### +################################################################################################### + +variable sys_cpu_interconnect_index +variable sys_hp0_interconnect_index +variable sys_hp1_interconnect_index +variable sys_hp2_interconnect_index +variable sys_hp3_interconnect_index +variable sys_mem_interconnect_index + +variable xcvr_index +variable xcvr_tx_index +variable xcvr_rx_index +variable xcvr_instance + +################################################################################################### +################################################################################################### + +set sys_cpu_interconnect_index 0 +set sys_hp0_interconnect_index -1 +set sys_hp1_interconnect_index -1 +set sys_hp2_interconnect_index -1 +set sys_hp3_interconnect_index -1 +set sys_mem_interconnect_index -1 + +set xcvr_index -1 +set xcvr_tx_index 0 +set xcvr_rx_index 0 +set xcvr_instance NONE + +################################################################################################### +################################################################################################### + +proc ad_ip_instance {i_ip i_name} { + + create_bd_cell -type ip -vlnv [get_ipdefs -all -filter "VLNV =~ *:${i_ip}:* && \ + design_tool_contexts =~ *IPI* && UPGRADE_VERSIONS == \"\""] ${i_name} +} + +proc ad_ip_parameter {i_name i_param i_value} { + + set_property ${i_param} ${i_value} [get_bd_cells ${i_name}] +} + +################################################################################################### +################################################################################################### + +proc ad_connect_type {p_name} { + + set m_name "" + + if {$m_name eq ""} {set m_name [get_bd_intf_pins -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_pins -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_intf_ports -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_ports -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_intf_nets -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_nets -quiet $p_name]} + + return $m_name +} + +proc ad_connect {p_name_1 p_name_2} { + + if {($p_name_2 eq "GND") || ($p_name_2 eq "VCC")} { + set p_size 1 + set p_msb [get_property left [get_bd_pins $p_name_1]] + set p_lsb [get_property right [get_bd_pins $p_name_1]] + if {($p_msb ne "") && ($p_lsb ne "")} { + set p_size [expr (($p_msb + 1) - $p_lsb)] + } + set p_cell_name [regsub -all {/} $p_name_1 "_"] + set p_cell_name "${p_cell_name}_${p_name_2}" + if {$p_name_2 eq "VCC"} { + set p_value -1 + } else { + set p_value 0 + } + ad_ip_instance xlconstant $p_cell_name + set_property CONFIG.CONST_WIDTH $p_size [get_bd_cells $p_cell_name] + set_property CONFIG.CONST_VAL $p_value [get_bd_cells $p_cell_name] + puts "connect_bd_net $p_cell_name/dout $p_name_1" + connect_bd_net [get_bd_pins $p_cell_name/dout] [get_bd_pins $p_name_1] + return + } + + set m_name_1 [ad_connect_type $p_name_1] + set m_name_2 [ad_connect_type $p_name_2] + + if {$m_name_1 eq ""} { + if {[get_property CLASS $m_name_2] eq "bd_intf_pin"} { + puts "create_bd_intf_net $p_name_1" + create_bd_intf_net $p_name_1 + } + if {[get_property CLASS $m_name_2] eq "bd_pin"} { + puts "create_bd_net $p_name_1" + create_bd_net $p_name_1 + } + set m_name_1 [ad_connect_type $p_name_1] + } + + if {[get_property CLASS $m_name_1] eq "bd_intf_pin"} { + puts "connect_bd_intf_net $m_name_1 $m_name_2" + connect_bd_intf_net $m_name_1 $m_name_2 + return + } + + if {[get_property CLASS $m_name_1] eq "bd_pin"} { + puts "connect_bd_net $m_name_1 $m_name_2" + connect_bd_net $m_name_1 $m_name_2 + return + } + + if {[get_property CLASS $m_name_1] eq "bd_net"} { + puts "connect_bd_net -net $m_name_1 $m_name_2" + connect_bd_net -net $m_name_1 $m_name_2 + return + } +} + +proc ad_disconnect {p_name_1 p_name_2} { + + set m_name_1 [ad_connect_type $p_name_1] + set m_name_2 [ad_connect_type $p_name_2] + + if {[get_property CLASS $m_name_1] eq "bd_net"} { + disconnect_bd_net $m_name_1 $m_name_2 + return + } + + if {[get_property CLASS $m_name_1] eq "bd_port"} { + delete_bd_objs -quiet [get_bd_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_1]] + delete_bd_objs -quiet $m_name_1 + return + } + + if {[get_property CLASS $m_name_1] eq "bd_pin"} { + delete_bd_objs -quiet [get_bd_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_1]] + delete_bd_objs -quiet $m_name_1 + return + } +} + +proc ad_reconct {p_name_1 p_name_2} { + + set m_name_1 [ad_connect_type $p_name_1] + set m_name_2 [ad_connect_type $p_name_2] + + if {[get_property CLASS $m_name_1] eq "bd_pin"} { + delete_bd_objs -quiet [get_bd_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_1]] + delete_bd_objs -quiet [get_bd_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_2]] + } + + if {[get_property CLASS $m_name_1] eq "bd_intf_pin"} { + delete_bd_objs -quiet [get_bd_intf_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_1]] + delete_bd_objs -quiet [get_bd_intf_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_2]] + } + + ad_connect $p_name_1 $p_name_2 +} + +################################################################################################### +################################################################################################### + +# +# lane_map maps the logical lane $n onto the physical lane $lane_map[$n]. If no +# lane map is provided logical lane $n is mapped onto physical lane $n. +# +proc ad_xcvrcon {u_xcvr a_xcvr a_jesd {lane_map {}}} { + + global xcvr_index + global xcvr_tx_index + global xcvr_rx_index + global xcvr_instance + + set no_of_lanes [get_property CONFIG.NUM_OF_LANES [get_bd_cells $a_xcvr]] + set qpll_enable [get_property CONFIG.QPLL_ENABLE [get_bd_cells $a_xcvr]] + set tx_or_rx_n [get_property CONFIG.TX_OR_RX_N [get_bd_cells $a_xcvr]] + +# set jesd204_vlnv [get_property VLNV $a_jesd] +# +# if {[string first "analog.com" $jesd204_vlnv] == 0} { +# set jesd204_type 0 +# } elseif {[string first "xilinx.com" $jesd204_vlnv] == 0} { +# set jesd204_type 1 +# } else { +# return -code 1 "Unsupported JESD204 core type." +# } + + set jesd204_bd_type [get_property TYPE [get_bd_cells $a_jesd]] + + if {$jesd204_bd_type == "hier"} { + set jesd204_type 0 + } else { + set jesd204_type 1 + } + + if {$xcvr_instance ne $u_xcvr} { + set xcvr_index [expr ($xcvr_index + 1)] + set xcvr_tx_index 0 + set xcvr_rx_index 0 + set xcvr_instance $u_xcvr + } + + set txrx "rx" + set data_dir "I" + set ctrl_dir "O" + set index $xcvr_rx_index + + if {$tx_or_rx_n == 1} { + + set txrx "tx" + set data_dir "O" + set ctrl_dir "I" + set index $xcvr_tx_index + } + + set m_sysref ${txrx}_sysref_${index} + set m_sync ${txrx}_sync_${index} + set m_data ${txrx}_data + + if {$xcvr_index >= 1} { + + set m_sysref ${txrx}_sysref_${xcvr_index}_${index} + set m_sync ${txrx}_sync_${xcvr_index}_${index} + set m_data ${txrx}_data_${xcvr_index} + } + + create_bd_port -dir I $m_sysref + create_bd_port -dir ${ctrl_dir} $m_sync + ad_ip_instance proc_sys_reset ${a_jesd}_rstgen + + for {set n 0} {$n < $no_of_lanes} {incr n} { + + set m [expr ($n + $index)] + + if {$tx_or_rx_n == 0} { + ad_connect ${a_xcvr}/up_es_${n} ${u_xcvr}/up_es_${m} + if {$jesd204_type == 0} { + ad_connect ${a_jesd}/phy_en_char_align ${u_xcvr}/${txrx}_calign_${m} + } else { + ad_connect ${a_jesd}/rxencommaalign_out ${u_xcvr}/${txrx}_calign_${m} + } + } + + if {(($m%4) == 0) && ($qpll_enable == 1)} { + ad_connect ${a_xcvr}/up_cm_${n} ${u_xcvr}/up_cm_${m} + } + + if {$lane_map != {}} { + set phys_lane [expr [lindex $lane_map $n] + $index] + } else { + set phys_lane $m + } + + ad_connect ${a_xcvr}/up_ch_${n} ${u_xcvr}/up_${txrx}_${m} + ad_connect ${u_xcvr}/${txrx}_out_clk_${index} ${u_xcvr}/${txrx}_clk_${m} + if {$jesd204_type == 0} { + ad_connect ${u_xcvr}/${txrx}_${phys_lane} ${a_jesd}/${txrx}_phy${n} + } else { + ad_connect ${u_xcvr}/${txrx}_${phys_lane} ${a_jesd}/gt${n}_${txrx} + } + + create_bd_port -dir ${data_dir} ${m_data}_${m}_p + create_bd_port -dir ${data_dir} ${m_data}_${m}_n + ad_connect ${u_xcvr}/${txrx}_${m}_p ${m_data}_${m}_p + ad_connect ${u_xcvr}/${txrx}_${m}_n ${m_data}_${m}_n + } + + if {$jesd204_type == 0} { + ad_connect ${a_jesd}/sysref $m_sysref + ad_connect ${a_jesd}/sync $m_sync + ad_connect ${u_xcvr}/${txrx}_out_clk_${index} ${a_jesd}/device_clk +# if {$tx_or_rx_n == 0} { +# ad_connect ${a_xcvr}/up_status ${a_jesd}/phy_ready +# } + } else { + ad_connect ${a_jesd}/${txrx}_sysref $m_sysref + ad_connect ${a_jesd}/${txrx}_sync $m_sync + ad_connect ${u_xcvr}/${txrx}_out_clk_${index} ${a_jesd}/${txrx}_core_clk + ad_connect ${a_xcvr}/up_status ${a_jesd}/${txrx}_reset_done + ad_connect ${a_jesd}_rstgen/peripheral_reset ${a_jesd}/${txrx}_reset + } + + ad_connect ${u_xcvr}/${txrx}_out_clk_${index} ${a_jesd}_rstgen/slowest_sync_clk + ad_connect sys_cpu_resetn ${a_jesd}_rstgen/ext_reset_in + + if {$tx_or_rx_n == 0} { + set xcvr_rx_index [expr ($xcvr_rx_index + $no_of_lanes)] + } + + if {$tx_or_rx_n == 1} { + set xcvr_tx_index [expr ($xcvr_tx_index + $no_of_lanes)] + } +} + +proc ad_xcvrpll {m_src m_dst} { + + foreach p_dst [get_bd_pins -quiet $m_dst] { + connect_bd_net [ad_connect_type $m_src] $p_dst + } +} + +################################################################################################### +################################################################################################### + +proc ad_mem_hp0_interconnect {p_clk p_name} { + + global sys_zynq + + if {($sys_zynq == 0) && ($p_name eq "sys_ps7/S_AXI_HP0")} {return} + if {$sys_zynq == 0} {ad_mem_hpx_interconnect "MEM" $p_clk $p_name} + if {$sys_zynq >= 1} {ad_mem_hpx_interconnect "HP0" $p_clk $p_name} +} + +proc ad_mem_hp1_interconnect {p_clk p_name} { + + global sys_zynq + + if {($sys_zynq == 0) && ($p_name eq "sys_ps7/S_AXI_HP1")} {return} + if {$sys_zynq == 0} {ad_mem_hpx_interconnect "MEM" $p_clk $p_name} + if {$sys_zynq >= 1} {ad_mem_hpx_interconnect "HP1" $p_clk $p_name} +} + +proc ad_mem_hp2_interconnect {p_clk p_name} { + + global sys_zynq + + if {($sys_zynq == 0) && ($p_name eq "sys_ps7/S_AXI_HP2")} {return} + if {$sys_zynq == 0} {ad_mem_hpx_interconnect "MEM" $p_clk $p_name} + if {$sys_zynq >= 1} {ad_mem_hpx_interconnect "HP2" $p_clk $p_name} +} + +proc ad_mem_hp3_interconnect {p_clk p_name} { + + global sys_zynq + + if {($sys_zynq == 0) && ($p_name eq "sys_ps7/S_AXI_HP3")} {return} + if {$sys_zynq == 0} {ad_mem_hpx_interconnect "MEM" $p_clk $p_name} + if {$sys_zynq >= 1} {ad_mem_hpx_interconnect "HP3" $p_clk $p_name} +} + +################################################################################################### +################################################################################################### + +proc ad_mem_hpx_interconnect {p_sel p_clk p_name} { + + global sys_zynq + global sys_ddr_addr_seg + global sys_hp0_interconnect_index + global sys_hp1_interconnect_index + global sys_hp2_interconnect_index + global sys_hp3_interconnect_index + global sys_mem_interconnect_index + + set p_name_int $p_name + set p_clk_source [get_bd_pins -filter {DIR == O} -of_objects [get_bd_nets $p_clk]] + + if {$p_sel eq "MEM"} { + if {$sys_mem_interconnect_index < 0} { + ad_ip_instance axi_interconnect axi_mem_interconnect + } + set m_interconnect_index $sys_mem_interconnect_index + set m_interconnect_cell [get_bd_cells axi_mem_interconnect] + set m_addr_seg [get_bd_addr_segs -of_objects [get_bd_cells axi_ddr_cntrl]] + } + + if {($p_sel eq "HP0") && ($sys_zynq == 1)} { + if {$sys_hp0_interconnect_index < 0} { + set p_name_int sys_ps7/S_AXI_HP0 + set_property CONFIG.PCW_USE_S_AXI_HP0 {1} [get_bd_cells sys_ps7] + ad_ip_instance axi_interconnect axi_hp0_interconnect + } + set m_interconnect_index $sys_hp0_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp0_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps7/S_AXI_HP0/HP0_DDR_LOWOCM] + } + + if {($p_sel eq "HP1") && ($sys_zynq == 1)} { + if {$sys_hp1_interconnect_index < 0} { + set p_name_int sys_ps7/S_AXI_HP1 + set_property CONFIG.PCW_USE_S_AXI_HP1 {1} [get_bd_cells sys_ps7] + ad_ip_instance axi_interconnect axi_hp1_interconnect + } + set m_interconnect_index $sys_hp1_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp1_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps7/S_AXI_HP1/HP1_DDR_LOWOCM] + } + + if {($p_sel eq "HP2") && ($sys_zynq == 1)} { + if {$sys_hp2_interconnect_index < 0} { + set p_name_int sys_ps7/S_AXI_HP2 + set_property CONFIG.PCW_USE_S_AXI_HP2 {1} [get_bd_cells sys_ps7] + ad_ip_instance axi_interconnect axi_hp2_interconnect + } + set m_interconnect_index $sys_hp2_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp2_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps7/S_AXI_HP2/HP2_DDR_LOWOCM] + } + + if {($p_sel eq "HP3") && ($sys_zynq == 1)} { + if {$sys_hp3_interconnect_index < 0} { + set p_name_int sys_ps7/S_AXI_HP3 + set_property CONFIG.PCW_USE_S_AXI_HP3 {1} [get_bd_cells sys_ps7] + ad_ip_instance axi_interconnect axi_hp3_interconnect + } + set m_interconnect_index $sys_hp3_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp3_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps7/S_AXI_HP3/HP3_DDR_LOWOCM] + } + + if {($p_sel eq "HP0") && ($sys_zynq == 2)} { + if {$sys_hp0_interconnect_index < 0} { + set p_name_int sys_ps8/S_AXI_HP0_FPD + set_property CONFIG.PSU__USE__S_AXI_GP2 {1} [get_bd_cells sys_ps8] + ad_ip_instance axi_interconnect axi_hp0_interconnect + } + set m_interconnect_index $sys_hp0_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp0_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps8/S_AXI_HP0_FPD/PLLPD_DDR_LOW] + } + + if {($p_sel eq "HP1") && ($sys_zynq == 2)} { + if {$sys_hp1_interconnect_index < 0} { + set p_name_int sys_ps8/S_AXI_HP1_FPD + set_property CONFIG.PSU__USE__S_AXI_GP3 {1} [get_bd_cells sys_ps8] + ad_ip_instance axi_interconnect axi_hp1_interconnect + } + set m_interconnect_index $sys_hp1_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp1_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps8/S_AXI_HP1_FPD/HP0_DDR_LOW] + } + + if {($p_sel eq "HP2") && ($sys_zynq == 2)} { + if {$sys_hp2_interconnect_index < 0} { + set p_name_int sys_ps8/S_AXI_HP2_FPD + set_property CONFIG.PSU__USE__S_AXI_GP4 {1} [get_bd_cells sys_ps8] + ad_ip_instance axi_interconnect axi_hp2_interconnect + } + set m_interconnect_index $sys_hp2_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp2_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps8/S_AXI_HP2_FPD/HP1_DDR_LOW] + } + + if {($p_sel eq "HP3") && ($sys_zynq == 2)} { + if {$sys_hp3_interconnect_index < 0} { + set p_name_int sys_ps8/S_AXI_HP3_FPD + set_property CONFIG.PSU__USE__S_AXI_GP5 {1} [get_bd_cells sys_ps8] + ad_ip_instance axi_interconnect axi_hp3_interconnect + } + set m_interconnect_index $sys_hp3_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp3_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps8/S_AXI_HP3_FPD/HP2_DDR_LOW] + } + + set i_str "S$m_interconnect_index" + if {$m_interconnect_index < 10} { + set i_str "S0$m_interconnect_index" + } + + set m_interconnect_index [expr $m_interconnect_index + 1] + + set p_intf_name [lrange [split $p_name_int "/"] end end] + set p_cell_name [lrange [split $p_name_int "/"] 0 0] + set p_intf_clock [get_bd_pins -filter "TYPE == clk && (CONFIG.ASSOCIATED_BUSIF == ${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ ${p_intf_name}:* || CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name}:*)" -quiet -of_objects [get_bd_cells $p_cell_name]] + if {[find_bd_objs -quiet -relation connected_to $p_intf_clock] ne "" || + $p_intf_clock eq $p_clk_source} { + set p_intf_clock "" + } + + regsub clk $p_clk resetn p_rst + if {[get_bd_nets -quiet $p_rst] eq ""} { + set p_rst sys_cpu_resetn + } + + if {$m_interconnect_index == 0} { + set_property CONFIG.NUM_MI 1 $m_interconnect_cell + set_property CONFIG.NUM_SI 1 $m_interconnect_cell + ad_connect $p_rst $m_interconnect_cell/ARESETN + ad_connect $p_clk $m_interconnect_cell/ACLK + ad_connect $p_rst $m_interconnect_cell/M00_ARESETN + ad_connect $p_clk $m_interconnect_cell/M00_ACLK + ad_connect $m_interconnect_cell/M00_AXI $p_name_int + if {$p_intf_clock ne ""} { + ad_connect $p_clk $p_intf_clock + } + } else { + set_property CONFIG.NUM_SI $m_interconnect_index $m_interconnect_cell + ad_connect $p_rst $m_interconnect_cell/${i_str}_ARESETN + ad_connect $p_clk $m_interconnect_cell/${i_str}_ACLK + ad_connect $m_interconnect_cell/${i_str}_AXI $p_name_int + if {$p_intf_clock ne ""} { + ad_connect $p_clk $p_intf_clock + } + assign_bd_address $m_addr_seg + } + + if {$m_interconnect_index > 1} { + set_property CONFIG.STRATEGY {2} $m_interconnect_cell + } + + if {$p_sel eq "MEM"} {set sys_mem_interconnect_index $m_interconnect_index} + if {$p_sel eq "HP0"} {set sys_hp0_interconnect_index $m_interconnect_index} + if {$p_sel eq "HP1"} {set sys_hp1_interconnect_index $m_interconnect_index} + if {$p_sel eq "HP2"} {set sys_hp2_interconnect_index $m_interconnect_index} + if {$p_sel eq "HP3"} {set sys_hp3_interconnect_index $m_interconnect_index} + +} + +################################################################################################### +################################################################################################### + +proc ad_cpu_interconnect {p_address p_name} { + + global sys_zynq + global sys_cpu_interconnect_index + + set i_str "M$sys_cpu_interconnect_index" + if {$sys_cpu_interconnect_index < 10} { + set i_str "M0$sys_cpu_interconnect_index" + } + + if {$sys_cpu_interconnect_index == 0} { + ad_ip_instance axi_interconnect axi_cpu_interconnect + if {$sys_zynq == 2} { + ad_connect sys_cpu_clk sys_ps8/maxihpm0_lpd_aclk + ad_connect sys_cpu_clk axi_cpu_interconnect/ACLK + ad_connect sys_cpu_clk axi_cpu_interconnect/S00_ACLK + ad_connect sys_cpu_resetn axi_cpu_interconnect/ARESETN + ad_connect sys_cpu_resetn axi_cpu_interconnect/S00_ARESETN + ad_connect axi_cpu_interconnect/S00_AXI sys_ps8/M_AXI_HPM0_LPD + } + if {$sys_zynq == 1} { + ad_connect sys_cpu_clk sys_ps7/M_AXI_GP0_ACLK + ad_connect sys_cpu_clk axi_cpu_interconnect/ACLK + ad_connect sys_cpu_clk axi_cpu_interconnect/S00_ACLK + ad_connect sys_cpu_resetn axi_cpu_interconnect/ARESETN + ad_connect sys_cpu_resetn axi_cpu_interconnect/S00_ARESETN + ad_connect axi_cpu_interconnect/S00_AXI sys_ps7/M_AXI_GP0 + } + if {$sys_zynq == 0} { + ad_connect sys_cpu_clk axi_cpu_interconnect/ACLK + ad_connect sys_cpu_clk axi_cpu_interconnect/S00_ACLK + ad_connect sys_cpu_resetn axi_cpu_interconnect/ARESETN + ad_connect sys_cpu_resetn axi_cpu_interconnect/S00_ARESETN + ad_connect axi_cpu_interconnect/S00_AXI sys_mb/M_AXI_DP + } + } + + if {$sys_zynq == 2} { + set sys_addr_cntrl_space [get_bd_addr_spaces sys_ps8/Data] + } + if {$sys_zynq == 1} { + set sys_addr_cntrl_space [get_bd_addr_spaces sys_ps7/Data] + } + if {$sys_zynq == 0} { + set sys_addr_cntrl_space [get_bd_addr_spaces sys_mb/Data] + } + + set sys_cpu_interconnect_index [expr $sys_cpu_interconnect_index + 1] + + + set p_cell [get_bd_cells $p_name] + set p_intf [get_bd_intf_pins -filter "MODE == Slave && VLNV == xilinx.com:interface:aximm_rtl:1.0"\ + -of_objects $p_cell] + + set p_hier_cell $p_cell + set p_hier_intf $p_intf + + while {$p_hier_intf != "" && [get_property TYPE $p_hier_cell] == "hier"} { + set p_hier_intf [find_bd_objs -boundary_type lower \ + -relation connected_to $p_hier_intf] + if {$p_hier_intf != {}} { + set p_hier_cell [get_bd_cells -of_objects $p_hier_intf] + } else { + set p_hier_cell {} + } + } + + set p_intf_clock "" + set p_intf_reset "" + + if {$p_hier_cell != {}} { + set p_intf_name [lrange [split $p_hier_intf "/"] end end] + + set p_intf_clock [get_bd_pins -filter "TYPE == clk && \ + (CONFIG.ASSOCIATED_BUSIF == ${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ ${p_intf_name}:* || \ + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name}:*)" \ + -quiet -of_objects $p_hier_cell] + set p_intf_reset [get_bd_pins -filter "TYPE == rst && \ + (CONFIG.ASSOCIATED_BUSIF == ${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ ${p_intf_name}:* || + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name}:*)" \ + -quiet -of_objects $p_hier_cell] + + if {($p_intf_clock ne "") && ($p_intf_reset eq "")} { + set p_intf_reset [get_property CONFIG.ASSOCIATED_RESET [get_bd_pins ${p_intf_clock}]] + if {$p_intf_reset ne ""} { + set p_intf_reset [get_bd_pins -filter "NAME == $p_intf_reset" -of_objects $p_hier_cell] + } + } + + # Trace back up + set p_hier_cell2 $p_hier_cell + + while {$p_intf_clock != {} && $p_hier_cell2 != $p_cell && $p_hier_cell2 != {}} { + puts $p_intf_clock + puts $p_hier_cell2 + set p_intf_clock [find_bd_objs -boundary_type upper \ + -relation connected_to $p_intf_clock] + if {$p_intf_clock != {}} { + set p_intf_clock [get_bd_pins [get_property PATH $p_intf_clock]] + set p_hier_cell2 [get_bd_cells -of_objects $p_intf_clock] + } + } + + set p_hier_cell2 $p_hier_cell + + while {$p_intf_reset != {} && $p_hier_cell2 != $p_cell && $p_hier_cell2 != {}} { + set p_intf_reset [find_bd_objs -boundary_type upper \ + -relation connected_to $p_intf_reset] + if {$p_intf_reset != {}} { + set p_intf_reset [get_bd_pins [get_property PATH $p_intf_reset]] + set p_hier_cell2 [get_bd_cells -of_objects $p_intf_reset] + } + } + } + + + if {[find_bd_objs -quiet -relation connected_to $p_intf_clock] ne ""} { + set p_intf_clock "" + } + if {$p_intf_reset ne ""} { + if {[find_bd_objs -quiet -relation connected_to $p_intf_reset] ne ""} { + set p_intf_reset "" + } + } + + set_property CONFIG.NUM_MI $sys_cpu_interconnect_index [get_bd_cells axi_cpu_interconnect] + + ad_connect sys_cpu_clk axi_cpu_interconnect/${i_str}_ACLK + if {$p_intf_clock ne ""} { + ad_connect sys_cpu_clk ${p_intf_clock} + } + ad_connect sys_cpu_resetn axi_cpu_interconnect/${i_str}_ARESETN + if {$p_intf_reset ne ""} { + ad_connect sys_cpu_resetn ${p_intf_reset} + } + ad_connect axi_cpu_interconnect/${i_str}_AXI ${p_intf} + + set p_seg [get_bd_addr_segs -of_objects $p_hier_cell] + set p_index 0 + foreach p_seg_name $p_seg { + if {$p_index == 0} { + set p_seg_range [get_property range $p_seg_name] + if {$p_seg_range < 0x1000} { + set p_seg_range 0x1000 + } + if {$sys_zynq == 2} { + if {($p_address >= 0x40000000) && ($p_address <= 0x4fffffff)} { + set p_address [expr ($p_address + 0x40000000)] + } + if {($p_address >= 0x70000000) && ($p_address <= 0x7fffffff)} { + set p_address [expr ($p_address + 0x20000000)] + } + } + create_bd_addr_seg -range $p_seg_range \ + -offset $p_address $sys_addr_cntrl_space \ + $p_seg_name "SEG_data_${p_name}" + } else { + assign_bd_address $p_seg_name + } + incr p_index + } +} + +################################################################################################### +################################################################################################### + +proc ad_cpu_interrupt {p_ps_index p_mb_index p_name} { + + global sys_zynq + + if {$sys_zynq == 0} {set p_index_int $p_mb_index} + if {$sys_zynq >= 1} {set p_index_int $p_ps_index} + + set p_index [regsub -all {[^0-9]} $p_index_int ""] + set m_index [expr ($p_index - 8)] + + if {($sys_zynq == 2) && ($p_index <= 7)} { + set p_net [get_bd_nets -of_objects [get_bd_pins sys_concat_intc_0/In$p_index]] + set p_pin [find_bd_objs -relation connected_to [get_bd_pins sys_concat_intc_0/In$p_index]] + + puts "delete_bd_objs $p_net $p_pin" + delete_bd_objs $p_net $p_pin + ad_connect sys_concat_intc_0/In$p_index $p_name + } + + if {($sys_zynq == 2) && ($p_index >= 8)} { + set p_net [get_bd_nets -of_objects [get_bd_pins sys_concat_intc_1/In$m_index]] + set p_pin [find_bd_objs -relation connected_to [get_bd_pins sys_concat_intc_1/In$m_index]] + + puts "delete_bd_objs $p_net $p_pin" + delete_bd_objs $p_net $p_pin + ad_connect sys_concat_intc_1/In$m_index $p_name + } + + if {$sys_zynq <= 1} { + + set p_net [get_bd_nets -of_objects [get_bd_pins sys_concat_intc/In$p_index]] + set p_pin [find_bd_objs -relation connected_to [get_bd_pins sys_concat_intc/In$p_index]] + + puts "delete_bd_objs $p_net $p_pin" + delete_bd_objs $p_net $p_pin + ad_connect sys_concat_intc/In$p_index $p_name + } +} + +################################################################################################### +################################################################################################### + diff --git a/CI/projects/scripts/adi_prcfg_project.tcl b/CI/projects/scripts/adi_prcfg_project.tcl new file mode 100644 index 00000000..a154849c --- /dev/null +++ b/CI/projects/scripts/adi_prcfg_project.tcl @@ -0,0 +1,201 @@ +#------------------------------------------------------------------------------- +# Processes for non-project mode development flow used for partial reconfiguration +#------------------------------------------------------------------------------- + +# Initialize the workspace +proc prcfg_init_workspace {prcfg_name_list} { + + # directory names + set static_dir "prcfg_static" + set sdk_dir "sdk_export" + + # make/clean all directory for design files + if {![file exists $static_dir]} { + file mkdir $static_dir + } else { + file delete -force $static_dir + file mkdir $static_dir + } + + foreach i $prcfg_name_list { + if {![file exists prcfg_$i]} { + file mkdir prcfg_$i + } else { + file delete -force prcfg_$i + file mkdir prcfg_$i + } + } + + if {![file exists $sdk_dir]} { + file mkdir $sdk_dir + } else { + file delete -force $sdk_dir + file mkdir $sdk_dir + } +} + +# Create and synthesize the static part of the project +proc prcfg_synth_static { verilog_files xdc_files } { + + global ad_hdl_dir + global ad_phdl_dir + global part + global board + + # location of the generated block design file + set system_project_dir ".srcs/sources_1/bd/system" + + # create project in mememory + create_project -in_memory -part $part + set_property board $board [current_project] + + # setup repo for library + set lib_dirs $ad_hdl_dir/library + lappend lib_dirs $ad_phdl_dir/library + + set_property ip_repo_paths $lib_dirs [current_fileset] + update_ip_catalog + + # create bd design + + create_bd_design "system" + source system_bd.tcl + + generate_target all [get_files $system_project_dir/system.bd] + make_wrapper -files [get_files $system_project_dir/system.bd] -top + read_verilog $system_project_dir/hdl/system_wrapper.v + + # add project files + read_verilog $verilog_files + read_xdc $xdc_files + + # run shyntesis + file mkdir "./prcfg_static/logs" + synth_design -mode default -top system_top -part $part > "./prcfg_static/logs/synth_static.rds" + + # generate hardware specification file for sdk + export_hardware [get_files .srcs/sources_1/bd/system/system.bd] -dir "./sdk_export" + + # write checkpoint + file mkdir "./prcfg_static/checkpoints" + write_checkpoint -force "./prcfg_static/checkpoints/synth_static.dcp" + close_project +} + +# Create and synthesize the reconfigurable part of the project +proc prcfg_synth_reconf { prcfg_name verilog_files } { + + global ad_hdl_dir + global ad_phdl_dir + global part + + create_project -in_memory -part $part + + # add project files + read_verilog $verilog_files + + # run OOC synthesis + file mkdir "./prcfg_${prcfg_name}/logs" + synth_design -mode out_of_context -top "prcfg_system_top" -part $part > "./prcfg_${prcfg_name}/logs/synth_${prcfg_name}.rds" + + # write checkpoint + file mkdir "./prcfg_${prcfg_name}/checkpoints" + write_checkpoint -force "./prcfg_${prcfg_name}/checkpoints/synth_${prcfg_name}.dcp" + close_project +} + +# Make the implementation of the project +proc prcfg_impl { xdc_file reconfig_name_list } { + + global part + + for { set i 0 } { $i < [llength $reconfig_name_list] } { incr i } { + set prcfg_name [lindex $reconfig_name_list $i] + if { $i == 0 } { + + open_checkpoint "./prcfg_static/checkpoints/synth_static.dcp" -part $part + + # Create the RP area on the fabric and load the default logic on it + read_xdc $xdc_file + read_checkpoint -cell i_prcfg_system_top "./prcfg_${prcfg_name}/checkpoints/synth_${prcfg_name}.dcp" + set_property HD.RECONFIGURABLE 1 [get_cells i_prcfg_system_top] + # implement the first configurations + opt_design > "./prcfg_${prcfg_name}/logs/opt_${prcfg_name}.rds" + # generate ltx file for debug probes + write_debug_probes -force "./debug_nets.ltx" + place_design > "./prcfg_${prcfg_name}/logs/place_${prcfg_name}.rds" + route_design > "./prcfg_${prcfg_name}/logs/route_${prcfg_name}.rds" + + # save results + save_results $prcfg_name + + # clear out RM + update_design -cell i_prcfg_system_top -black_box + + # save static-only route + write_checkpoint -force "./prcfg_static/checkpoints/route_static_only.dcp" + + close_project + } else { + + open_checkpoint "./prcfg_static/checkpoints/route_static_only.dcp" -part $part + + # implement the next configuration + # with the static-only design loaded in memory, lock down all placement and route + lock_design -level routing + + read_checkpoint -cell i_prcfg_system_top "./prcfg_${prcfg_name}/checkpoints/synth_${prcfg_name}.dcp" + opt_design > "./prcfg_${prcfg_name}/logs/opt_${prcfg_name}.rds" + place_design > "./prcfg_${prcfg_name}/logs/place_${prcfg_name}.rds" + route_design > "./prcfg_${prcfg_name}/logs/route_${prcfg_name}.rds" + + # save results + save_results $prcfg_name + + close_project + } + } +} + +# Save the result of an implementation, generate reports +proc save_results { prcfg_name } { + + file mkdir "./prcfg_${prcfg_name}/results" + # checkpoint to the routed design + write_checkpoint -force "./prcfg_${prcfg_name}/results/top_route_design.dcp" + # reports + report_utilization -pblocks pblock_adi -file "./prcfg_${prcfg_name}/results/top_utilization.rpt" + report_timing_summary -file "./prcfg_${prcfg_name}/results/top_timing_summary.rpt" + # checkpoint to the routed RP + write_checkpoint -force -cell i_prcfg_system_top "./prcfg_${prcfg_name}/checkpoints/route_rm_${prcfg_name}.dcp" + +} + +# Verify the compatibility of different configurations +proc prcfg_verify { prcfg_name_list } { + + file mkdir "./verify_design" + + set prcfg_init_path "./prcfg_[lindex $prcfg_name_list 0]/results/top_route_design.dcp" + set prcfg_additional_paths "" + + for {set i 1} {$i < [llength $prcfg_name_list]} {incr i} { + lappend prcfg_additional_paths "./prcfg_[lindex $prcfg_name_list $i]/results/top_route_design.dcp" + } + + pr_verify -full_check -initial $prcfg_init_path -additional $prcfg_additional_paths -file ./verify_design/pr_verify.log + +} + +# Generate bitstream +proc prcfg_gen_bit { prcfg_name_list } { + + global part + + foreach i $prcfg_name_list { + open_checkpoint "./prcfg_${i}/results/top_route_design.dcp" -part $part + file mkdir "./prcfg_${i}/bit" + write_bitstream -force -bin_file -file "./prcfg_${i}/bit/config_${i}.bit" + close_project + } +} diff --git a/CI/projects/scripts/adi_tquest.tcl b/CI/projects/scripts/adi_tquest.tcl new file mode 100644 index 00000000..a8f5d4a7 --- /dev/null +++ b/CI/projects/scripts/adi_tquest.tcl @@ -0,0 +1,24 @@ + +report_timing -detail full_path -npaths 20 -file timing_impl.log + +set worst_path [get_timing_paths -npaths 1 -setup] +foreach_in_collection path $worst_path { + set slack [get_path_info $path -slack] +} + +if {$slack > 0} { + set worst_path [get_timing_paths -npaths 1 -hold] + foreach_in_collection path $worst_path { + set slack [get_path_info $path -slack] + } +} + +if {$slack < 0} { + set sof_files [glob *.sof] + foreach sof_file $sof_files { + set root_sof_file [file rootname $sof_file] + set new_sof_file [append root_sof_file "_timing.sof"] + file rename -force $sof_file $new_sof_file + } + return -code error [format "ERROR: Timing Constraints NOT met!"] +} diff --git a/CI/projects/scripts/fixmake.sh b/CI/projects/scripts/fixmake.sh new file mode 100755 index 00000000..c14d8d2a --- /dev/null +++ b/CI/projects/scripts/fixmake.sh @@ -0,0 +1,3 @@ +grep "CC_FLAGS :=" pmufw/Makefile | grep -e "-Os" || sed -i '/-mxl-soft-mul/ s/$/ -Os -flto -ffat-lto-objects/' pmufw/Makefile +cd pmufw +make \ No newline at end of file diff --git a/CI/projects/scripts/fsbl_build.tcl b/CI/projects/scripts/fsbl_build.tcl new file mode 100644 index 00000000..653e5916 --- /dev/null +++ b/CI/projects/scripts/fsbl_build.tcl @@ -0,0 +1,41 @@ + +if { $argc != 3 } { + set fpga_board "ZC706" +} else { + set fpga_board [lindex $argv 1] +} +puts "===========" +puts $fpga_board +puts "===========" + +set cdir [pwd] +set sdk_loc $cdir/vivado_prj.sdk + +# Create the SDK project +hsi open_hw_design $sdk_loc/system_top.hdf +set cpu_name [lindex [hsi get_cells -filter {IP_TYPE==PROCESSOR}] 0] +sdk set_workspace $sdk_loc +sdk create_hw_project -name hw_0 -hwspec $sdk_loc/system_top.hdf + +# Create project +if {$fpga_board eq "ZCU102"} { + sdk create_app_project -name fsbl -hwproject hw_0 -proc $cpu_name -os standalone -lang C -app {Zynq MP FSBL} +} else { + sdk create_app_project -name fsbl -hwproject hw_0 -proc $cpu_name -os standalone -lang C -app {Zynq FSBL} +} + +sdk configapp -app fsbl build-config release +sdk build_project -type all + +# Collect necessary files +file copy -force $cdir/projects/common/boot/zynq.bif $cdir/boot/zynq.bif +file copy -force $sdk_loc/fsbl/Release/fsbl.elf $cdir/boot/fsbl.elf +file copy -force $sdk_loc/hw_0/system_top.bit $cdir/boot/system_top.bit +cd $cdir/boot + +# Create the BOOT.bin +if {$fpga_board eq "ZCU102"} { +exec bootgen -image $cdir/boot/zynqmp.bif -w -o i $cdir/boot/BOOT.BIN +} else { +exec bootgen -image $cdir/boot/zynq.bif -w -o i $cdir/boot/BOOT.BIN +} diff --git a/CI/projects/scripts/fsbl_build_zynq.tcl b/CI/projects/scripts/fsbl_build_zynq.tcl new file mode 100644 index 00000000..92ae603c --- /dev/null +++ b/CI/projects/scripts/fsbl_build_zynq.tcl @@ -0,0 +1,29 @@ + + +### Calling script must have system_top.hdf u-boot.elf + + +set cdir [pwd] +set sdk_loc $cdir/vivado_prj.sdk + +### Create fsbl +hsi open_hw_design $sdk_loc/system_top.hdf +set cpu_name [lindex [hsi get_cells -filter {IP_TYPE==PROCESSOR}] 0] +sdk setws $sdk_loc +sdk createhw -name hw_0 -hwspec $sdk_loc/system_top.hdf +sdk createapp -name fsbl -hwproject hw_0 -proc $cpu_name -os standalone -lang C -app {Zynq FSBL} +configapp -app fsbl build-config release +sdk projects -build -type all + +### Copy common zynq.bif file +file copy -force $cdir/projects/common/boot/zynq.bif $cdir/boot/zynq.bif + +### Copy fsbl and system_top.bit into the output folder +file copy -force $sdk_loc/fsbl/Release/fsbl.elf $cdir/boot/fsbl.elf +file copy -force $sdk_loc/hw_0/system_top.bit $cdir/boot/system_top.bit + +### Build BOOT.BIN +cd $cdir/boot +exec bootgen -arch zynq -image zynq.bif -o BOOT.BIN -w +exit + diff --git a/CI/projects/scripts/fsbl_build_zynqmp.tcl b/CI/projects/scripts/fsbl_build_zynqmp.tcl new file mode 100644 index 00000000..e72cab87 --- /dev/null +++ b/CI/projects/scripts/fsbl_build_zynqmp.tcl @@ -0,0 +1,34 @@ + + +### Calling script must have system_top.hdf u-boot.elf + + +set cdir [pwd] +set sdk_loc $cdir/vivado_prj.sdk + +### Create fsbl +hsi open_hw_design $sdk_loc/system_top.hdf +set cpu_name [lindex [hsi get_cells -filter {IP_TYPE==PROCESSOR}] 0] +sdk setws $sdk_loc +sdk createhw -name hw_0 -hwspec $sdk_loc/system_top.hdf +sdk createapp -name fsbl -hwproject hw_0 -proc $cpu_name -os standalone -lang C -app {Zynq MP FSBL} +configapp -app fsbl build-config release +sdk projects -build -type all + +### Create create_pmufw_project.tcl +#set hwdsgn [open_hw_design $sdk_loc/system_top.hdf] +#generate_app -hw $hwdsgn -os standalone -proc psu_pmu_0 -app zynqmp_pmufw -sw pmufw -dir pmufw + +### Copy common zynqmp.bif and bl31.elf file +file copy -force $cdir/projects/common/boot/zynqmp.bif $cdir/boot/zynqmp.bif +file copy -force $cdir/projects/common/boot/bl31.elf $cdir/boot/bl31.elf + +### Copy fsbl and system_top.bit into the output folder +file copy -force $sdk_loc/fsbl/Release/fsbl.elf $cdir/boot/fsbl.elf +file copy -force $sdk_loc/hw_0/system_top.bit $cdir/boot/system_top.bit +file copy -force $cdir/pmufw/executable.elf $cdir/boot/pmufw.elf + +### Build BOOT.BIN +cd $cdir/boot +exec bootgen -arch zynqmp -image zynqmp.bif -o BOOT.BIN -w +exit diff --git a/CI/projects/scripts/pmufw_zynqmp.tcl b/CI/projects/scripts/pmufw_zynqmp.tcl new file mode 100644 index 00000000..ec456f8b --- /dev/null +++ b/CI/projects/scripts/pmufw_zynqmp.tcl @@ -0,0 +1,8 @@ + +set cdir [pwd] +set sdk_loc $cdir/vivado_prj.sdk + +### Create create_pmufw_project.tcl +set hwdsgn [open_hw_design $sdk_loc/system_top.hdf] +generate_app -hw $hwdsgn -os standalone -proc psu_pmu_0 -app zynqmp_pmufw -sw pmufw -dir pmufw +quit diff --git a/CI/scripts/Docker b/CI/scripts/Docker new file mode 100644 index 00000000..6c95c6fb --- /dev/null +++ b/CI/scripts/Docker @@ -0,0 +1,10 @@ +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 new file mode 100644 index 00000000..44954f2b --- /dev/null +++ b/CI/scripts/Makefile @@ -0,0 +1,71 @@ +# Usage: +# make MLRELEASE= HDLBRANCH= +# Example +# make build MLRELEASE=R2018b HDLBRANCH=hdl_2018_r1 + +SHELL := /bin/bash + +MLFLAGS := -nodisplay -nodesktop -nosplash + +ifeq ($(MLRELEASE),) +MLRELEASE := R2019a +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 + +test_installer: + cd ../.. ; \ + cp *.mltbx test/ ; \ + ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('test');runInstallerTests;" + +test: + cd ../.. ; \ + ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "cd('test');runTests('$(BOARD)');" + +test_streaming: + cd ../.. ; \ + ${MLPATH}/$(MLRELEASE)/bin/matlab $(MLFLAGS) -r "addpath(genpath('test'));runHWTests;" + +test_synth: + bash synth_designs.sh + +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/AnalogDevicesSensorToolbox_$(GITTAG).zip doc sensor_examples info.xml LICENSE README.md test/*.log diff --git a/CI/scripts/adi_build.tcl b/CI/scripts/adi_build.tcl new file mode 100644 index 00000000..486e59e9 --- /dev/null +++ b/CI/scripts/adi_build.tcl @@ -0,0 +1,71 @@ +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 +if {$fpga_board eq "ZCU102"} { + + ### Copy common boot files + file copy -force $cdir/projects/common/boot/zynqmp.bif $cdir/boot/zynqmp.bif + file copy -force $cdir/projects/common/boot/bl31.elf $cdir/boot/bl31.elf + file copy -force $cdir/projects/common/boot/pmufw.elf $cdir/boot/pmufw.elf + file copy -force $cdir/projects/common/boot/fsbl.elf $cdir/boot/fsbl.elf + file copy -force $cdir/projects/common/boot/u-boot-zcu.elf $cdir/boot/u-boot-zcu.elf + + ### Copy system_top.bit into the output folder + file copy -force vivado_prj.runs/impl_1/system_top.bit $cdir/boot/system_top.bit + + # Generate BOOT.bin File + cd $cdir/boot + exec bootgen -arch zynqmp -image zynqmp.bif -o BOOT.BIN -w + cd $cdir + 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_ip.tcl b/CI/scripts/adi_ip.tcl new file mode 100644 index 00000000..2ccd9b15 --- /dev/null +++ b/CI/scripts/adi_ip.tcl @@ -0,0 +1,387 @@ +## ############################################################################################### +## ############################################################################################### +## check tool version + +if {![info exists REQUIRED_VIVADO_VERSION]} { + set REQUIRED_VIVADO_VERSION "2018.2" +} + +if {[info exists ::env(ADI_IGNORE_VERSION_CHECK)]} { + set IGNORE_VERSION_CHECK 1 +} elseif {![info exists IGNORE_VERSION_CHECK]} { + set IGNORE_VERSION_CHECK 0 +} + +## ############################################################################################### +## ############################################################################################### +## ip related stuff + +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 the simulation file set +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 +} + +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]] + } + set f [ipx::add_file $ip_bd_files $proj_filegroup] + set_property -dict [list \ + type tclSource \ + ] $f +} + +proc adi_ip_infer_streaming_interfaces {ip_name} { + + ipx::infer_bus_interfaces xilinx.com:interface:axis_rtl:1.0 [ipx::current_core] + +} + +proc adi_ip_infer_mm_interfaces {ip_name} { + + ipx::infer_bus_interfaces xilinx.com:interface:aximm_rtl:1.0 [ipx::current_core] + +} + +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 + } + } +} + +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 +} + +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 +} + +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 + } +} + +proc adi_add_multi_bus {num bus_name_prefix mode abs_type bus_type port_maps dependency} { + for {set i 0} {$i < 8} {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 + } + } +} + +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 + } + } +} + +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 + } + } +} + +## ############################################################################################### +## ############################################################################################### +## ip related stuff + +variable ip_constr_files + +proc adi_ip_create {ip_name} { + + global ad_hdl_dir + global ad_phdl_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_phdl_dir} { + lappend lib_dirs $ad_phdl_dir/library + } + + set_property ip_repo_paths $lib_dirs [current_fileset] + update_ip_catalog +} + +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 +} + +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 +} + +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 +} + +## ############################################################################################### +## ############################################################################################### +## interface related stuff + +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] +} + +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] +} + +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 new file mode 100644 index 00000000..f777ff29 --- /dev/null +++ b/CI/scripts/adi_project.tcl @@ -0,0 +1,205 @@ + +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 "2018.2" +} + +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}} { + + 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 + create_bd_design "system" + source $project_dir/system_bd.tcl + if {$project_name_org != "adrv9361z7035_ccbox_lvds_modem"} { + source $project_dir/$update_tcl + } + + + 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/bsp.tmpl b/CI/scripts/bsp.tmpl new file mode 100644 index 00000000..e81d8087 --- /dev/null +++ b/CI/scripts/bsp.tmpl @@ -0,0 +1,159 @@ + + + Analog Devices, Inc. High Speed Converter Toolbox + Travis Collins + travis.collins@analog.com + Analog Devices, Inc + Board support package for data streaming from Analog Devices high speed converters. + Scripts and tools created by ADI to be used with MATLAB and Simulink with ADI high speed converters +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}/Analog Devices Board Support Packages.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 + + + 40075943-d2d1-4d90-8e59-b3eff5f58180 + % +CI/* +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}/hsx_examples + + + + + + + __REPO-ROOT__/AnalogDevicesHighSpeedConverterToolbox.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.sh b/CI/scripts/build_bsp.sh new file mode 100644 index 00000000..0068d807 --- /dev/null +++ b/CI/scripts/build_bsp.sh @@ -0,0 +1,160 @@ +#!/bin/bash +if [ -z "${HDLBRANCH}" ]; then +HDLBRANCH='hdl_2018_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 +if ! git clone --single-branch -b $HDLBRANCH https://github.com/analogdevicesinc/hdl.git +then + exit 1 +fi + +# Get required vivado version needed for HDL +VER=$(awk '/set REQUIRED_VIVADO_VERSION/ {print $3}' hdl/library/scripts/adi_ip.tcl | 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 + + + +# Pack IP cores +echo "Starting IP core packaging" +vivado -mode batch -source scripts/pack_all_ips.tcl > /dev/null 2>&1 + +# Repack i2s and i2c cores to include xml files +cd hdl/library/axi_i2s_adi/ +unzip analog.com_user_axi_i2s_adi_1.0.zip -d tmp +rm analog.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 * +cp analog.com_user_axi_i2s_adi_1.0.zip ../ +cd ../../../.. + +cd hdl/library/util_i2c_mixer/ +unzip analog.com_user_util_i2c_mixer_1.0.zip -d tmp/ +rm analog.com_user_util_i2c_mixer_1.0.zip +cp *.xml tmp/ +cd tmp +zip -r analog.com_user_util_i2c_mixer_1.0.zip * +cp analog.com_user_util_i2c_mixer_1.0.zip ../ +cd ../../../.. + + +# Move all cores +echo "Moving all cores" +vivado -mode batch -source scripts/copy_all_packed_ips.tcl > /dev/null 2>&1 + +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 +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_wa_bsp/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 unused projects +TO_KEEP="daq2 common scripts" +DIRS=$(find hdl/projects -maxdepth 1 -type d ) + +for d in $DIRS +do + REMOVE=1 + for tk in $TO_KEEP + do + if [[ "hdl/projects/$tk" == "$d" ]]; then + echo "$d" + REMOVE=0 + fi + if [[ "hdl/projects" == "$d" ]]; then + echo "$d" + REMOVE=0 + fi + done + if [ $REMOVE = 1 ]; then + echo "Removing: $d" + rm -rf "$d" + fi +done +rm hdl/projects/Makefile + +# 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 new file mode 100644 index 00000000..d7628a4f --- /dev/null +++ b/CI/scripts/copy_all_packed_ips.tcl @@ -0,0 +1,69 @@ + + +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} + 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 + + +cd ../../.. diff --git a/CI/scripts/dockermake b/CI/scripts/dockermake new file mode 100755 index 00000000..06c93222 --- /dev/null +++ b/CI/scripts/dockermake @@ -0,0 +1,3 @@ +#!/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 new file mode 100644 index 00000000..1ad8a6a8 --- /dev/null +++ b/CI/scripts/genTlbx.m @@ -0,0 +1,95 @@ +function genTlbx(examples) + +if nargin==0 + examples = 0; +end + +version = '19.1.1'; +ml = ver('MATLAB'); +ml = ml.Release(2:end-1); + + +%% +cd(fileparts((mfilename('fullpath')))); +cd('../..'); +p = pwd; +cd(fileparts((mfilename('fullpath')))); + +if examples + fid = fopen('bsp.tmpl','r'); +else + error('Non-Examples build not available'); +end +f=fread(fid,'*char')'; +fclose(fid); + +f = strrep(f,'__REPO-ROOT__',p); +f = strrep(f,'__VERSION__',version); +f = strrep(f,'__ML-RELEASE__',ml); + +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','hsx_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 = ['AnalogDevicesHighSpeedConverterToolbox_v',currentVersion]; +else + outputFile = ['AnalogDevicesHighSpeedConverterToolbox_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/hdl_build.md b/CI/scripts/hdl_build.md new file mode 100644 index 00000000..33ddabe8 --- /dev/null +++ b/CI/scripts/hdl_build.md @@ -0,0 +1,6 @@ +### Flow of HDL WA Project Build + +- daq2/zcu102/system_project_rxtx.tcl + - daq2/zcu102/config_rxtx.tcl + - daq2/zcu102/config_prj.tcl # Configure AXI Interconnect + - daq2/common/config_rxtx.tcl # Port manipulation diff --git a/CI/scripts/linter.m b/CI/scripts/linter.m new file mode 100644 index 00000000..4a26bff9 --- /dev/null +++ b/CI/scripts/linter.m @@ -0,0 +1,23 @@ +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 new file mode 100644 index 00000000..f749efec --- /dev/null +++ b/CI/scripts/pack_all_ips.tcl @@ -0,0 +1,53 @@ + +# Create zip of IP cores +proc pack_ip_core {} { + + 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.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 + +# Pack Xilinx cores +cd xilinx +pack_ip_core +cd .. + +# Pack JESD cores +cd jesd204 +pack_ip_core +cd .. + +# Pack spi_engine cores +cd spi_engine +pack_ip_core +cd .. + +cd ../../ diff --git a/CI/scripts/setupDocker.sh b/CI/scripts/setupDocker.sh new file mode 100755 index 00000000..eca338c0 --- /dev/null +++ b/CI/scripts/setupDocker.sh @@ -0,0 +1,8 @@ +#!/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 new file mode 100644 index 00000000..4cfc89b2 --- /dev/null +++ b/CI/scripts/synth_designs.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +MLFLAGS="-nodisplay -nodesktop -nosplash" + +if [ -z "$MLRELEASE" ] +then + MLRELEASE=R2018b +fi + +MLPATH=/usr/local/MATLAB + +cd ../.. +source /opt/Xilinx/Vivado/2018.2/settings64.sh +Xvfb :77 & +export DISPLAY=:77 +export SWT_GTK3=0 +source /opt/Xilinx/Vivado/2018.2/settings64.sh +$MLPATH/$MLRELEASE/bin/matlab $MLFLAGS -r "cd('test');runSynthTests;" +kill -9 `pidof Xvfb` diff --git a/README.md b/README.md index b29aa92c..3be37b11 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,28 @@ -# HighSpeedConverterToolbox -MATLAB toolbox for ADI high speed converter products +# Analog Devices, Inc. High Speed Converter Toolbox + +Toolbox created by ADI to be used with MATLAB and Simulink with ADI high speed converters. + +License : [![License](https://img.shields.io/badge/license-LGPL2-blue.svg)](https://github.com/analogdevicesinc/HighSpeedConverterToolbox/blob/master/LICENSE) +Latest Release : [![GitHub release](https://img.shields.io/github/release/analogdevicesinc/HighSpeedConverterToolbox.svg)](https://github.com/analogdevicesinc/HighSpeedConverterToolbox/releases/latest) +Downloads : [![Github All Releases](https://img.shields.io/github/downloads/analogdevicesinc/HighSpeedConverterToolbox/total.svg)](https://github.com/analogdevicesinc/HighSpeedConverterToolbox/releases/latest) + +As with many open source packages, we use [GitHub](https://github.com/analogdevicesinc/HighSpeedConverterToolbox) to do develop and maintain the source, and [GitLab](https://GitLab.com/) for continuous integration. + - If you want to just use HighSpeedConverterToolbox, we suggest using the [latest release](https://github.com/analogdevicesinc/HighSpeedConverterToolbox/releases/latest). + - If you think you have found a bug in the release, or need a feature which isn't in the release, try the latest **untested** builds from the master branch. + +| HDL Branch | GitHub master status | MATLAB Release | Installer Package | +|:-----------------------:|:---------------------:|:-------:|:-------------------:| +| 2018_R2 | [![pipeline status](https://gitlab.com/tfcollins/HighSpeedConverterToolbox/badges/master/pipeline.svg)](https://gitlab.com/tfcollins/HighSpeedConverterToolbox/commits/master) | 2019a | | + +If you use it, and like it - please let us know. If you use it, and hate it - please let us know that too. + +## Supported Tools and Releases + +We provide support for certain releases of MATLAB. This does not mean older releases will not work but they are not maintained. Currently supported tools are: +- Bug fixes and new features: MATLAB R2019a with Vivado 2018.2 + +## Support and Documentation + +All support questions should be posted in our [EngineerZone](https://ez.analog.com/linux-device-drivers/linux-software-drivers) forums. Documentation is included within the toolbox but additional documentation is avaible on the [ADI Wiki](https://wiki.analog.com/resources/eval/user-guides/matlab_bsp). + + diff --git a/doc/Examples.html b/doc/Examples.html new file mode 100644 index 00000000..e623cd81 --- /dev/null +++ b/doc/Examples.html @@ -0,0 +1,14 @@ + +ADI High Speed Converter Toolbox Examples

ADI High Speed Converter Toolbox Examples

Streaming Examples

  • DAQ2 Basic Streaming
+
+ \ No newline at end of file diff --git a/doc/Support.html b/doc/Support.html new file mode 100644 index 00000000..821c89b7 --- /dev/null +++ b/doc/Support.html @@ -0,0 +1,22 @@ + +ADI High Speed Converter Toolbox Support

ADI High Speed Converter Toolbox Support

Support is provided online through the EngineerZone forums. If you have questions related to the hardware itself outside of this BSP, contact your local FAE or ask on the forums.
Question regarding specific aspect of the BSP should be asked in the following places:
+
+ \ No newline at end of file diff --git a/doc/SupportedHardware.html b/doc/SupportedHardware.html new file mode 100644 index 00000000..b8e3d939 --- /dev/null +++ b/doc/SupportedHardware.html @@ -0,0 +1,28 @@ + +ADI High Speed Converter Toolbox Supported Hardware

ADI High Speed Converter Toolbox Supported Hardware

Almost any ADI hardware that has an IIO supported driver can stream data into MATLAB or Simulink. We have specific implementations of the following devices, boards, or chips that support streaming:

System Requirements

Specific examples will require different toolboxes. The examples will require:
All device I/O support with System objects or Blocks requires:
+
+ \ No newline at end of file diff --git a/doc/SystemObjects.html b/doc/SystemObjects.html new file mode 100644 index 00000000..46260b50 --- /dev/null +++ b/doc/SystemObjects.html @@ -0,0 +1,55 @@ + +ADI High Speed Converter Toolbox System Objects For Device I/O

ADI High Speed Converter Toolbox System Objects For Device I/O

All ADI streaming interfaces share the same general API. Simply insert you specific part of development board:
rx = adi.<part_or_board_name>.Rx;
rx.uri = '<uri of board>';
receiveData = rx();
tx = adi.<part_or_board_name>.Tx;
tx.uri = '<uri of board>';
tx(receiveData);
Example:
rx = adi.AD9680.Rx
rx =
adi.AD9680.Rx with properties:
SamplingRate: 1.0000e+09
SamplesPerFrame: 32768
uri: 'ip:10.0.0.200'
EnabledChannels: 1
rx.uri = 'ip:analog';
rx.SamplesPerFrame = 16;
data = imu();
The following parts have device specific implementations:
  • AD9680
  • AD9144
  • AD9680

+
+ \ No newline at end of file diff --git a/doc/adi_bsp.html b/doc/adi_bsp.html new file mode 100644 index 00000000..f8b4da75 --- /dev/null +++ b/doc/adi_bsp.html @@ -0,0 +1,37 @@ + +Analog Devices Inc. High Speed Converters Toolbox

Analog Devices Inc. High Speed Converters Toolbox

This Board Support Package (BSP) provides streaming support for Analog Devices Inc. (ADI) high speed converters.

Supported Hardware

System Requirements

Specific examples will require different toolboxes. The examples will require:
All device I/O support with System objects or Blocks requires:

Support

Help and support for the is provided exclusively on-line. If you don't have an internet connection on this computer, please find one that does.

Further Documentation

Please refer to the ADI wiki for more in-depth information for libiio, drivers, and hardware functionality.
+
+ \ No newline at end of file diff --git a/doc/adi_logo.png b/doc/adi_logo.png new file mode 100644 index 00000000..b19682ea Binary files /dev/null and b/doc/adi_logo.png differ diff --git a/doc/helptoc.xml b/doc/helptoc.xml new file mode 100644 index 00000000..1f9503ab --- /dev/null +++ b/doc/helptoc.xml @@ -0,0 +1,10 @@ + + + Analog Devices, Inc Sensor Toolbox + + System Objects + Supported Hardware + Examples + Support + + diff --git a/hdl/common/+hdlbsp/+util/+SDUpdater/DeviceTypes.m b/hdl/common/+hdlbsp/+util/+SDUpdater/DeviceTypes.m new file mode 100644 index 00000000..ab653fab --- /dev/null +++ b/hdl/common/+hdlbsp/+util/+SDUpdater/DeviceTypes.m @@ -0,0 +1,6 @@ +classdef DeviceTypes + enumeration + ZYNQ, ALTERA_SOC + end +end + diff --git a/hdl/common/+hdlbsp/+util/+SDUpdater/FWModes.m b/hdl/common/+hdlbsp/+util/+SDUpdater/FWModes.m new file mode 100644 index 00000000..5a23852a --- /dev/null +++ b/hdl/common/+hdlbsp/+util/+SDUpdater/FWModes.m @@ -0,0 +1,6 @@ +classdef FWModes + enumeration + FAT32_ZIP, DISK_IMAGE + end +end + diff --git a/hdl/common/+hdlbsp/+util/+SDUpdater/SDUpdater.m b/hdl/common/+hdlbsp/+util/+SDUpdater/SDUpdater.m new file mode 100644 index 00000000..9cfcc030 --- /dev/null +++ b/hdl/common/+hdlbsp/+util/+SDUpdater/SDUpdater.m @@ -0,0 +1,476 @@ +classdef SDUpdater < handle + properties (Hidden) + handles; %Graphics objects + BoardRDTable; % Table of boards / reference designs + VideoPSPDir; % Root PSP directory + SDList; % List of SD objects + BoardVariantTable = containers.Map(); % Table of boards / variants / zip files + end + + properties (Hidden, Constant) + FWMODE_ZIP = 'FAT32 ZIP'; + FWMODE_IMG = 'Disk Image'; + DEVICETYPE_ZYNQ = 'Zynq'; + DEVICETYPE_ALTERASOC = 'Altera SoC'; + end + + properties + AppName = 'SD Updater' + FWMode@hdlbsp.util.SDUpdater.FWModes = hdlbsp.util.SDUpdater.FWModes.FAT32_ZIP; + DeviceType@hdlbsp.util.SDUpdater.DeviceTypes = hdlbsp.util.SDUpdater.DeviceTypes.ZYNQ; + GUIEnabled@logical = true; + end + + properties (Access = protected) + FWUpdater + privActiveVariant + privActiveBoard + privActiveSDDrive = 'N/A' + end + + properties (Dependent) + ActiveSDDrive + ActiveZip + ActiveVariant + ActiveBoard + end + + properties (Hidden, Dependent) + WipeSD % Preserve SD card contents on udpate + ActiveBoardObj + ActiveVariantList + DriveList + end + + methods (Hidden) + function app = SDUpdater(varargin) + % Configure the app + app.configureApp; + + % Load the variants + app.loadVariants; + + % Launch the app + app.launchApp; + end + + function delete(app) + try %#ok + delete(app.handles.Fig); + end + end + + function createGUI(app) + LeftTextAlgin = 10; + LeftMenuAlign = 150; + MenuHeight = 27; + LineSize = 40; + CurrentVertPos = LineSize*7+10; + CheckboxWidth = 50; + + + % Create the GUI + app.handles.Fig = figure(... + 'Color',[0.94 0.94 0.94],... + 'Position',[532 624 500 CurrentVertPos],... + 'MenuBar','none',... + 'Name',app.AppName,... + 'NumberTitle','off',... + 'Resize','off',... + 'Visible','on',... + 'CloseRequestFcn', @app.callback_closeApp); + + % Create the SD card list + CurrentVertPos = CurrentVertPos - LineSize; + + app.handles.menuSDCard = app.uimenu(... + 'N/A', [LeftMenuAlign CurrentVertPos 61 MenuHeight],... + @app.callback_menuSDCard); + + app.handles.txtSDCard = app.uitext(... + 'Drive', [LeftTextAlgin CurrentVertPos]); + + app.handles.btnRefresh = uicontrol(... + 'Parent',app.handles.Fig,... + 'Callback',@app.callback_updateSDList,... + 'Position',[69 CurrentVertPos 60 MenuHeight],... + 'String','Refresh'); + + % Create the write button + app.handles.btnWrite = uicontrol(... + 'Parent',app.handles.Fig,... + 'Callback',@app.callback_WriteSD,... + 'Position',[390 CurrentVertPos 101 MenuHeight],... + 'String','Write SD'); + + % Create the board list + CurrentVertPos = CurrentVertPos - LineSize; + + app.handles.menuBoard = app.uimenu(... + 'N/A', [LeftMenuAlign CurrentVertPos 337 MenuHeight],... + @app.callback_menuBoard); + + app.handles.txtBrd = app.uitext(... + 'Board', [LeftTextAlgin CurrentVertPos]); + + % Create the reference design list + CurrentVertPos = CurrentVertPos - LineSize; + + app.handles.menuVariant = app.uimenu(... + 'N/A', [LeftMenuAlign CurrentVertPos 337 MenuHeight],... + @app.callback_menuVariant); + + app.handles.txtVariant = app.uitext(... + 'Variant', [LeftTextAlgin CurrentVertPos]); + + + if isequal(app.FWMode, hdlbsp.util.SDUpdater.FWModes.FAT32_ZIP) + % Create the preserve SD checkbox + CurrentVertPos = CurrentVertPos - LineSize; + + app.handles.txtWipeSD = app.uitext(... + 'Wipe SD Card', [LeftTextAlgin CurrentVertPos]); + + app.handles.checkWipeSD = uicontrol(... + 'Parent',app.handles.Fig,... + 'Position',[LeftMenuAlign CurrentVertPos CheckboxWidth MenuHeight],... + 'Callback',@app.callback_WipeSD,... + 'Style','checkbox',... + 'Value',app.WipeSD); + end + + end + + function handle = uitext(app, Text, Position) + % Set the width/height to 1 + Position(3:4) = 1; + + % Create the text control + handle = uicontrol(... + 'Parent',app.handles.Fig,... + 'Position',Position,... + 'HorizontalAlignment', 'Left',... + 'String',Text,... + 'Style','text'); + + % Resize based on the string + ext = get(handle, 'Extent'); + Position(3:4) = (ext(3:4))+3; + set(handle, 'Position', Position); + + end + + function handle = uimenu(app, Text, Position, Callback) + if nargin < 4 + Callback = {}; + end + handle = uicontrol(... + 'Parent',app.handles.Fig,... + 'BackgroundColor', [1 1 1 ],... + 'Position',Position,... + 'String',Text,... + 'BusyAction', 'cancel',... + 'Callback',Callback,... + 'Style','popupmenu',... + 'Value',1); + end + + function handle = uiedit(app, Text, Position, Callback) + if nargin < 4 + Callback = {}; + end + handle = uicontrol(... + 'Parent',app.handles.Fig,... + 'BackgroundColor', [1 1 1 ],... + 'Position',Position,... + 'String',Text,... + 'BusyAction', 'cancel',... + 'Callback',Callback,... + 'Style','edit',... + 'Value',1); + end + + end + %% GUI Callbacks + % Syntax: method(app,hObject,eventdata) + methods (Hidden) + + function callback_closeApp(app,varargin) + delete(app.handles.Fig); + delete(app); + end + + function callback_WriteSD(app,varargin) + app.enableUI(false); + cleanup = onCleanup(@()app.enableUI(true)); + + if isequal(app.getSelectedItem(app.handles.menuSDCard), 'N/A') + error('You must select a valid drive to program the SD card'); + end + + if app.WipeSD + warnVal = 'wipe all'; + else + warnVal = 'overwrite'; + end + WarnStr = sprintf(['WARNING: Updating the SD Card will %s existing contents\n'... + 'Are you sure you want to proceed?'], warnVal); + + ButtonName = questdlg(WarnStr, ... + 'Update SD Card', ... + 'No'); + if isequal(ButtonName, 'Yes') + app.writeSDCard(); + end + end + + function callback_updateSDList(app,varargin) + app.enableUI(false); + cleanup = onCleanup(@()app.enableUI(true)); + + driveList = app.updateSDList; + set(app.handles.menuSDCard, 'String', driveList) + end + + + function callback_menuSDCard(app,varargin) + app.privActiveSDDrive = app.getSelectedItem(app.handles.menuSDCard); + end + + function callback_menuBoard(app,varargin) + app.ActiveBoard = app.getSelectedItem(app.handles.menuBoard); + set(app.handles.menuVariant, 'String', app.ActiveVariantList); + end + + function callback_menuVariant(app,varargin) + app.ActiveVariant = app.getSelectedItem(app.handles.menuVariant); + end + + function callback_WipeSD(app,varargin) + app.WipeSD = get(app.handles.checkWipeSD, 'Value'); + end + end + %% Set / Get Properties + methods + function val = get.WipeSD(app) + if isequal(app.FWMode, hdlbsp.util.SDUpdater.FWModes.FAT32_ZIP) + val = getpref('HDLBSP_COMMON', 'SDUpdater_WipeSD', 0); + else + val = 1; + end + end + + function set.WipeSD(app, val) %#ok + if isequal(val, 0) || isequal(val, 1) + setpref('HDLBSP_COMMON', 'SDUpdater_WipeSD', val); + else + error('Must specify 0 or 1 for WipeSD'); + end + end + + function variantList = get.ActiveVariantList(app) + boardObj = app.ActiveBoardObj(); + variantList = keys(boardObj.Variants); + end + + function brdObj = get.ActiveBoardObj(app) + brdObj = app.BoardVariantTable(app.ActiveBoard); + end + + function set.ActiveVariant(app, varName) + if ~ismember(varName, app.ActiveVariantList) + error('%s is not an available variant.', varName); + end + app.privActiveVariant = varName; + end + + function varName = get.ActiveVariant(app) + varName = app.privActiveVariant; + end + + function set.ActiveBoard(app, boardName) + if ~ismember(boardName, keys(app.BoardVariantTable)) + error('%s is not an available board.', boardName); + end + app.privActiveBoard = boardName; + end + + function boardName = get.ActiveBoard(app) + boardName = app.privActiveBoard; + end + + function zipFile = get.ActiveZip(app) + brdObj = app.ActiveBoardObj; + varName = app.ActiveVariant; + zipFile = brdObj.Variants(varName); + end + + function driveList = get.DriveList(app) + driveList = app.FWUpdater.getDriveList; + if isempty(driveList) + driveList = {'N/A'}; + end + end + + function set.ActiveSDDrive(app, sdDrive) + if ~ismember(sdDrive, app.DriveList) + error('%s is not an available SD card', sdDrive); + end + app.privActiveSDDrive = sdDrive; + end + + function sdDrive = get.ActiveSDDrive(app) + sdDrive = app.privActiveSDDrive; + end + + end + + %% API Functions + methods (Abstract, Access = protected) + % Configure the App settings + configureApp(app) + % Load the SD card variants + loadVariants(app) + end + + methods + % Update the SD card contents + function writeSDCard(app) + app.FWUpdater.Drive = app.ActiveSDDrive; + + switch(app.FWMode) + case hdlbsp.util.SDUpdater.FWModes.FAT32_ZIP + app.writeSDCard_FAT32; + case hdlbsp.util.SDUpdater.FWModes.DISK_IMAGE + app.writeSDCard_IMG; + otherwise + error('Invalid setting for FWMode'); + end + end + end + + methods (Access = protected) + function addVariant(app, BoardName, VariantName, ZipFile) + if app.BoardVariantTable.isKey(BoardName) + tblObj = app.BoardVariantTable(BoardName); + else + tblObj.BoardName = BoardName; + tblObj.Variants = containers.Map(); + end + tblObj.Variants(VariantName) = ZipFile; + % if it's the first one, set it to active + if isempty(app.privActiveBoard) + app.privActiveBoard = BoardName; + app.privActiveVariant = VariantName; + end + app.BoardVariantTable(BoardName) = tblObj; + end + + function launchApp(app) + % Load some parameters + if isempty(app.FWUpdater) + switch(app.DeviceType) + case hdlbsp.util.SDUpdater.DeviceTypes.ZYNQ + app.FWUpdater = zynq.setup.ZynqFirmwareUpdate; + case hdlbsp.util.SDUpdater.DeviceTypes.ALTERA_SOC + app.FWUpdater = codertarget.alterasoc.setup.AlteraSoCFirmwareUpdate; + end + end + + % Update the SD Card List + driveList = app.updateSDList; + + % Create the GUI + if app.GUIEnabled + app.createGUI(); + % Update the list of SD cards + set(app.handles.menuSDCard, 'String', driveList) + + % Setup the board list + set(app.handles.menuBoard, 'String', app.BoardVariantTable.keys); + app.setSelectedItem(app.handles.menuBoard, app.ActiveBoard); + + % Setup the variant list + set(app.handles.menuVariant, 'String', app.ActiveVariantList); + app.setSelectedItem(app.handles.menuVariant, app.ActiveVariant); + end + end + + % Update a FAT32 SD Card + function writeSDCard_FAT32(app) + hWaitbar = waitbar(0,['SD Card Update...' ... + char(ones(1,30, 'like', uint8(0)).*uint8(' '))]); + cleanup = onCleanup(@()delete(hWaitbar)); + + if app.WipeSD + waitbar(0.25,hWaitbar,'Formatting SD Card...'); + app.FWUpdater.formatFATWindows; + end + + % Program the SD Card + waitbar(0.50,hWaitbar,'Updating SD Card Contents...'); + unzip(app.ActiveZip, [app.ActiveSDDrive filesep]); + waitbar(0.75,hWaitbar,'Applying final updates...'); + end + + % Update a image SD Card + function writeSDCard_IMG(app) + fwDir = tempname; + mkdir(fwDir); + cleanup = onCleanup(@()rmdir(fwDir, 's')); + % Get the info on the image file + [~, fwFileName, ~] = fileparts(app.ActiveZip); + + % populate the FW Updater + app.FWUpdater.DownloadFolder = fwDir; + app.FWUpdater.FirmwareName = fwFileName; + gunzip(app.ActiveZip, fwDir); + + % Determine the file size + fileInfo = dir(fullfile(fwDir, fwFileName)); + app.FWUpdater.FirmwareSize = fileInfo.bytes; + % Write the image + app.FWUpdater.writeImage; + end + end + + %% Helper Functions + methods (Access = protected) + function driveList = updateSDList(app) + driveList = app.DriveList; + if ~ismember(app.ActiveSDDrive, driveList) + app.privActiveSDDrive = driveList{1}; + end + end + function enableUI(app, en) + elements = fields(app.handles); + for ii = 1:numel(elements) + handle = app.handles.(elements{ii}); + if ~isfield(get(handle), 'Enable') + continue; + end + if en + set(handle, 'Enable', 'on'); + else + set(handle, 'Enable', 'off'); + end + end + end + end + + %% Static Methods + methods (Hidden, Static) + function item = getSelectedItem(menu) + menuList = get(menu, 'String'); + item = menuList{get(menu, 'Value')}; + end + function setSelectedItem(menu, item) + menuList = get(menu, 'String'); + [is,Idx] = ismember(item, menuList); + if ~is + error('Could not find %s in list %s', item, menuList); + end + set(menu, 'Value', Idx); + end + end +end \ No newline at end of file diff --git a/hdl/common/+hdlbsp/+util/SDUpdater.m b/hdl/common/+hdlbsp/+util/SDUpdater.m new file mode 100644 index 00000000..3dbf7eb5 --- /dev/null +++ b/hdl/common/+hdlbsp/+util/SDUpdater.m @@ -0,0 +1,15 @@ +function SDUpdater(fhndl) + +persistent app cleanup; + +if ~isempty(cleanup) + cleanup = []; +end + +if ~ispc + error('The SD Updater is only supported on Windows platforms'); +end + +app = feval(fhndl); +cleanup = onCleanup(@()delete(app)); + diff --git a/hdl/common/+hdlbsp/+util/vendorInstall.m b/hdl/common/+hdlbsp/+util/vendorInstall.m new file mode 100644 index 00000000..e8dcb054 --- /dev/null +++ b/hdl/common/+hdlbsp/+util/vendorInstall.m @@ -0,0 +1,66 @@ +function vendorInstall(mode, dirs) +% hdlbsp.util.vendorInstall adds/removes vendor BSPs + +% Copyright 2015 MathWorks, Inc. All Rights Reserved. + + + %% Initialization + if mode == 0 + pathfunc = @addpath; + else + pathfunc = @rmpath; + end + + + % Determine the currently running version + mlRel = version('-release'); + mlRelNum = decodeRel(mlRel); + + % For each path to be added + for ii = 1:numel(dirs) + % add or remove the path + pathfunc(dirs{ii}); + + if (mode == 0) + % If we're adding a path, check for a Contents.m file + verInfo = ver(dirs{ii}); + if ~isempty(verInfo) + % Contents.m found, compare the versions + bspRel = regexprep(verInfo.Release, 'R|\(|\)', ''); + bspRelNum = decodeRel(bspRel); + + if mlRelNum > bspRelNum + % Target release is older-- warn about it + warning('%s is designed for R%s, but you are installing on R%s',... + verInfo.Name,bspRel,mlRel); + elseif mlRelNum < bspRelNum + % Target release is newer-- error out + error('%s is designed for R%s, but you are installing on R%s',... + verInfo.Name,bspRel,mlRel); + end + end + end + end + + % Save the path + status = savepath; + if status + error('Failed to save the path!'); + end + + %% Cleanup + rehash('toolboxreset'); + rehash('toolboxcache'); + updateHdlwaPlatformList('ip_core'); +end + +function relNum = decodeRel(relStr) + % Convert release string to a decimal number + % R2015a --> 2015.0 + % R2015b --> 2015.1 + relInfo = regexp(relStr,'R?(?\d+)(?a|b)', 'names'); + relNum = str2double(relInfo.year); + if isequal(relInfo.rel, 'b') + relNum = relNum + 0.1; + end +end \ No newline at end of file diff --git a/hdl/common/+hdlbsp/install.m b/hdl/common/+hdlbsp/install.m new file mode 100644 index 00000000..cb150831 --- /dev/null +++ b/hdl/common/+hdlbsp/install.m @@ -0,0 +1,22 @@ +function install(mode) +% hdlbsp.install adds/removes common BSP utilities + +% Copyright 2016 MathWorks, Inc. All Rights Reserved. + + if nargin == 0 + mode = 0; + end + + %% Initialization + % Determine where we're operating out of + hdlbspRootDir = fileparts(strtok(mfilename('fullpath'), '+')); + olddir = cd(hdlbspRootDir); % Make sure we can access the tools + cleanup = onCleanup(@()cd(olddir)); + + % Update the path + paths = {... + fullfile(hdlbspRootDir),... + }; + + hdlbsp.util.vendorInstall(mode,paths); +end \ No newline at end of file diff --git a/hdl/common/+hdlbsp/uninstall.m b/hdl/common/+hdlbsp/uninstall.m new file mode 100644 index 00000000..b3f7ef14 --- /dev/null +++ b/hdl/common/+hdlbsp/uninstall.m @@ -0,0 +1,7 @@ +function uninstall +% hdlbsp.uninstall removes common HDL BSP utilities + +% Copyright 2016 MathWorks, Inc. All Rights Reserved. + + hdlbsp.install(1); +end diff --git a/hdl/common/Contents.m b/hdl/common/Contents.m new file mode 100644 index 00000000..0b2c4aee --- /dev/null +++ b/hdl/common/Contents.m @@ -0,0 +1,2 @@ +% HDL Coder BSP Tools +% Version 1.07 (R2017b) 01-May-2018 diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+common/plugin_board.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+common/plugin_board.m new file mode 100644 index 00000000..0adbc9c5 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+common/plugin_board.m @@ -0,0 +1,36 @@ +function hB = plugin_board(board) +% Use Plugin API to create board plugin object + +hB = hdlcoder.Board; + +% Target Board Information +hB.BoardName = sprintf('AnalogDevices DAQ2 %s', upper(board)); + +% FPGA Device +hB.FPGAVendor = 'Xilinx'; +hB.FPGAFamily = 'Zynq UltraScale+'; + +% Determine the device based on the board +switch(upper(board)) +% case 'ZC706' +% hB.FPGADevice = sprintf('xc7%s', 'z045'); +% hB.FPGAPackage = 'ffg900'; +% hB.FPGASpeed = '-2'; + case 'ZCU102' + hB.FPGADevice = sprintf('xc%s', 'zu9eg-ffvb1156-2-e'); + hB.FPGAPackage = ''; + hB.FPGASpeed = ''; + otherwise + hB.FPGADevice = sprintf('xc%s', 'zu9eg-ffvb1156-2-e'); + hB.FPGAPackage = ''; + hB.FPGASpeed = ''; +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/+daq2/+common/plugin_rd.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+common/plugin_rd.m new file mode 100644 index 00000000..df3a2292 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+common/plugin_rd.m @@ -0,0 +1,71 @@ +function hRD = plugin_rd(board, design) +% Reference design definition + +% Construct reference design object +hRD = hdlcoder.ReferenceDesign('SynthesisTool', 'Xilinx Vivado'); + +% This is the base reference design that other RDs can build upon +hRD.ReferenceDesignName = sprintf('DAQ2 %s (%s)', upper(board), upper(design)); + +% Determine the board name based on the design +hRD.BoardName = sprintf('AnalogDevices DAQ2 %s', upper(board)); + +% Tool information +hRD.SupportedToolVersion = {'2018.2'}; + +% Get the root directory +rootDir = fileparts(strtok(mfilename('fullpath'), '+')); + +% Design files are shared +hRD.SharedRD = true; +hRD.SharedRDFolder = fullfile(rootDir, 'vivado'); + +%% Add custom design files +% add custom Vivado design +hRD.addCustomVivadoDesign( ... + 'CustomBlockDesignTcl', fullfile('projects', 'daq2', lower(board), 'system_project_rxtx.tcl'), ... + 'CustomTopLevelHDL', fullfile('projects', 'daq2', lower(board), 'system_top.v')); + +hRD.BlockDesignName = 'system'; + +% custom constraint files +hRD.CustomConstraints = {... + fullfile('projects', 'daq2', 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')..., + }; + +hRD.addParameter( ... + 'ParameterID', 'ref_design', ... + 'DisplayName', 'Reference Type', ... + 'DefaultValue', design); + +hRD.addParameter( ... + 'ParameterID', 'fpga_board', ... + 'DisplayName', 'FPGA Boad', ... + 'DefaultValue', upper(board)); + + +%% Add interfaces +% add clock interface +switch(upper(design)) + case 'RX' + hRD.addClockInterface( ... + 'ClockConnection', 'util_daq2_xcvr/rx_out_clk_0', ... + 'ResetConnection', 'axi_ad9680_jesd_rstgen/peripheral_aresetn'); + case 'TX' + hRD.addClockInterface( ... + 'ClockConnection', 'util_daq2_xcvr/tx_out_clk_0', ... + 'ResetConnection', 'axi_ad9144_jesd_rstgen/peripheral_aresetn'); +% case 'RX & TX' +% hRD.addClockInterface( ... +% 'ClockConnection', 'axi_adrv9009_rx_clkgen/clk_0', ... +% 'ResetConnection', 'sys_rstgen/peripheral_aresetn'); + otherwise + error('Unknown reference design'); +end diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/add_io.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/add_io.m new file mode 100644 index 00000000..64a701c6 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/add_io.m @@ -0,0 +1,94 @@ +function add_io(hRD,type) + +% add AXI4 and AXI4-Lite slave interfaces +hRD.addAXI4SlaveInterface( ... + 'InterfaceConnection', 'axi_cpu_interconnect/M08_AXI', ... % ADC DMA BUS + 'BaseAddress', '0x9D000000', ... + 'MasterAddressSpace', 'sys_ps8/Data'); + +%% Interface settings +rx_pack_core = 'axi_ad9680_cpack'; +rx_data_widths = 64; +rx_ports = 2; +rx_source_core = 'axi_ad9680_core'; + +tx_upack_core = 'axi_ad9144_upack'; +tx_data_widths = 64; +tx_ports = 2; +tx_sink_core = 'axi_ad9144_core'; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% RX IO +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +if contains(lower(type),'rx') + + %% Valids + hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data Valid OUT', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'dut_data_valid', ... + 'PortWidth', 1, ... + 'InterfaceConnection', [rx_pack_core,'/adc_valid_0'], ... + 'IsRequired', false); + hRD.addInternalIOInterface( ... + 'InterfaceID', 'DAQ2 Data Valid IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'dev_data_valid', ... + 'PortWidth', 1, ... + 'InterfaceConnection', [rx_source_core,'/adc_valid_0'], ... + 'IsRequired', false); + %% Data + for k=0:rx_ports-1 + % DUT outputs + hRD.addInternalIOInterface( ... + 'InterfaceID', ['IP Data ',num2str(k),' OUT'], ... + 'InterfaceType', 'OUT', ... + 'PortName', ['dut_data_',num2str(k)], ... + 'PortWidth', rx_data_widths, ... + 'InterfaceConnection', [rx_pack_core,'/adc_data_',num2str(k)]', ... + 'IsRequired', false); + % DUT inputs + hRD.addInternalIOInterface( ... + 'InterfaceID', ['DAQ2 ADC Data ',num2str(k),' IN'], ... + 'InterfaceType', 'IN', ... + 'PortName', ['daq2_adc_data_',num2str(k)], ... + 'PortWidth', rx_data_widths, ... + 'InterfaceConnection', [rx_source_core,'/adc_data_',num2str(k)], ... + 'IsRequired', false); + end +end +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TX IO +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +if contains(lower(type),'tx') + + %% Valids + hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data Valid IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'dut_data_valid', ... + 'PortWidth', 1, ... + 'InterfaceConnection', [tx_upack_core,'/dac_valid_out_0'], ... + 'IsRequired', false); + + %% Data + for k=0:tx_ports-1 + % DUT inputs + hRD.addInternalIOInterface( ... + 'InterfaceID', ['DMA Data ',num2str(k),' IN'], ... + 'InterfaceType', 'IN', ... + 'PortName', ['dma_data_',num2str(k)], ... + 'PortWidth', tx_data_widths, ... + 'InterfaceConnection', [tx_upack_core,'/dac_data_',num2str(k)], ... + 'IsRequired', false); + % DUT outputs + hRD.addInternalIOInterface( ... + 'InterfaceID', ['DAQ2 DAC Data ',num2str(k),' OUT'], ... + 'InterfaceType', 'OUT', ... + 'PortName', ['dut_data_',num2str(k)], ... + 'PortWidth', rx_data_widths, ... + 'InterfaceConnection', [tx_sink_core,'/dac_ddata_',num2str(k)]', ... + 'IsRequired', false); + end + +end diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/add_io.m~ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/add_io.m~ new file mode 100644 index 00000000..b10ec124 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/add_io.m~ @@ -0,0 +1,171 @@ +function add_io(hRD,type) + +% add AXI4 and AXI4-Lite slave interfaces +% hRD.addAXI4SlaveInterface( ... +% 'InterfaceConnection', 'axi_cpu_interconnect/M13_AXI', ... % ADC DMA BUS +% 'BaseAddress', '0x43C00000', ... +% 'MasterAddressSpace', 'sys_ps8/Data'); +hRD.addAXI4SlaveInterface( ... + 'InterfaceConnection', 'axi_cpu_interconnect/M13_AXI', ... % ADC DMA BUS + 'BaseAddress', '0x9D000000', ... + 'MasterAddressSpace', 'sys_ps8/Data'); + + +rx_pack_core = 'axi_ad9680_cpack'; +rx_data_widths = 64; +rx_ports = 2; +rx_source_core = 'axi_ad9680_core'; + +tx_upack_core = 'axi_ad9144_upack'; +tx_data_widths = 64; +tx_ports = 2; +tx_source_core = 'axi_ad9680_core'; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% RX IO +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +if contains(lower(type),'rx') + + %% Valids + hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data Valid OUT', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'dut_data_valid', ... + 'PortWidth', 1, ... + 'InterfaceConnection', [rx_pack_core,'/adc_valid_0'], ... + 'IsRequired', false); + hRD.addInternalIOInterface( ... + 'InterfaceID', 'DAQ2 Data Valid IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'dev_data_valid', ... + 'PortWidth', 1, ... + 'InterfaceConnection', [rx_source_core,'/adc_valid_0'], ... + 'IsRequired', false); + %% Data + for k=0:rx_ports-1 + % DUT outputs + hRD.addInternalIOInterface( ... + 'InterfaceID', ['IP Data ',num2str(k),' OUT'], ... + 'InterfaceType', 'OUT', ... + 'PortName', ['dut_data_',num2str(k)], ... + 'PortWidth', rx_data_widths, ... + 'InterfaceConnection', [rx_pack_core,'/adc_data_',num2str(k)]', ... + 'IsRequired', false); + % DUT inputs + hRD.addInternalIOInterface( ... + 'InterfaceID', ['DAQ2 ADC Data I',num2str(k)], ... + 'InterfaceType', 'IN', ... + 'PortName', ['daq2_adc_data_',num2str(k)], ... + 'PortWidth', rx_data_widths, ... + 'InterfaceConnection', [rx_source_core,'/adc_data_',num2str(k)], ... + 'IsRequired', false); + end +end +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TX IO +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +if contains(lower(type),'tx') + + %% Valids + hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data Valid IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'dut_data_valid', ... + 'PortWidth', 1, ... + 'InterfaceConnection', [tx_source_core,'/adc_valid_0'], ... + 'IsRequired', false); + hRD.addInternalIOInterface( ... + 'InterfaceID', 'DAQ2 Data Valid OUT', ... + 'InterfaceType', 'IN', ... + 'PortName', 'dev_data_valid', ... + 'PortWidth', 1, ... + 'InterfaceConnection', [tx_upack_core,'/adc_valid_0'], ... + 'IsRequired', false); + %% Data + for k=0:rx_ports-1 + % DUT outputs + hRD.addInternalIOInterface( ... + 'InterfaceID', ['IP Data ',num2str(k),' OUT'], ... + 'InterfaceType', 'OUT', ... + 'PortName', ['dut_data_',num2str(k)], ... + 'PortWidth', rx_data_widths, ... + 'InterfaceConnection', [rx_pack_core,'/adc_data_',num2str(k)]', ... + 'IsRequired', false); + % DUT inputs + hRD.addInternalIOInterface( ... + 'InterfaceID', ['DAQ2 ADC Data I',num2str(k)], ... + 'InterfaceType', 'IN', ... + 'PortName', ['daq2_adc_data_',num2str(k)], ... + 'PortWidth', rx_data_widths, ... + 'InterfaceConnection', [rx_source_core,'/adc_data_',num2str(k)], ... + 'IsRequired', false); + end + + + % Reference design interfaces + % Outputs from generated IP to ADRV9009 + hRD.addInternalIOInterface( ... + 'InterfaceID', 'ADRV9009 DAC Data I0', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_adrv9009_dac_data_i0', ... + 'PortWidth', 32, ... + 'InterfaceConnection', 'axi_adrv9009_core/dac_data_i0', ... + 'IsRequired', false); + + hRD.addInternalIOInterface( ... + 'InterfaceID', 'ADRV9009 DAC Data Q0', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_adrv9009_dac_data_q0', ... + 'PortWidth', 32, ... + 'InterfaceConnection', 'axi_adrv9009_core/dac_data_q0', ... + 'IsRequired', false); + + hRD.addInternalIOInterface( ... + 'InterfaceID', 'ADRV9009 DAC Data I1', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_adrv9009_dac_data_i1', ... + 'PortWidth', 32, ... + 'InterfaceConnection', 'axi_adrv9009_core/dac_data_i1', ... + 'IsRequired', false); + + hRD.addInternalIOInterface( ... + 'InterfaceID', 'ADRV9009 DAC Data Q1', ... + 'InterfaceType', 'OUT', ... + 'PortName', 'axi_adrv9009_dac_data_q1', ... + 'PortWidth', 32, ... + 'InterfaceConnection', 'axi_adrv9009_core/dac_data_q1', ... + 'IsRequired', false); + + % Inputs to generated IP from upack core + hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data 0 IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'util_dac_unpack_dac_data_00', ... + 'PortWidth', 32, ... + 'InterfaceConnection', 'util_adrv9009_tx_upack/dac_data_0', ... + 'IsRequired', false); + + hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data 1 IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'util_dac_unpack_dac_data_01', ... + 'PortWidth', 32, ... + 'InterfaceConnection', 'util_adrv9009_tx_upack/dac_data_1', ... + 'IsRequired', false); + + hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data 2 IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'util_dac_unpack_dac_data_02', ... + 'PortWidth', 32, ... + 'InterfaceConnection', 'util_adrv9009_tx_upack/dac_data_2', ... + 'IsRequired', false); + + hRD.addInternalIOInterface( ... + 'InterfaceID', 'IP Data 3 IN', ... + 'InterfaceType', 'IN', ... + 'PortName', 'util_dac_unpack_dac_data_03', ... + 'PortWidth', 32, ... + 'InterfaceConnection', 'util_adrv9009_tx_upack/dac_data_3', ... + 'IsRequired', false); +end diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/hdlcoder_ref_design_customization.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/hdlcoder_ref_design_customization.m new file mode 100644 index 00000000..1de0413c --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/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.daq2.zcu102.plugin_rd_rx', ... + 'AnalogDevices.daq2.zcu102.plugin_rd_tx', ... +...% 'AnalogDevices.daq2.zcu102.plugin_rd_rxtx', ... + }; + +boardName = 'AnalogDevices DAQ2 ZCU102'; + +end diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_board.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_board.m new file mode 100644 index 00000000..c380b32d --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/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.daq2.common.plugin_board('ZCU102'); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_rx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_rx.m new file mode 100644 index 00000000..49f9e5bd --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_rx.m @@ -0,0 +1,6 @@ +function hRD = plugin_rd_rx +% Reference design definition + +% Call the common reference design definition function +hRD = AnalogDevices.daq2.common.plugin_rd('ZCU102', 'Rx'); +AnalogDevices.daq2.zcu102.add_io(hRD, 'Rx'); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_rxtx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_rxtx.m new file mode 100644 index 00000000..1d3d9289 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_rxtx.m @@ -0,0 +1,8 @@ +function hRD = plugin_rd_rxtx +% Reference design definition + +% Copyright 2014-2015 The MathWorks, Inc. + +% Call the common reference design definition function +hRD = AnalogDevices.daq2.common.plugin_rd('ZCU102', 'Rx & Tx'); +AnalogDevices.daq2.zcu102.add_io(hRD, 'Rx & Tx'); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_tx.m b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_tx.m new file mode 100644 index 00000000..6feb7807 --- /dev/null +++ b/hdl/vendor/AnalogDevices/+AnalogDevices/+daq2/+zcu102/plugin_rd_tx.m @@ -0,0 +1,8 @@ +function hRD = plugin_rd_tx +% Reference design definition + +% Copyright 2014-2015 The MathWorks, Inc. + +% Call the common reference design definition function +hRD = AnalogDevices.daq2.common.plugin_rd('ZCU102', 'Tx'); +AnalogDevices.daq2.zcu102.add_io(hRD, 'Tx'); diff --git a/hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRAttributeInfo.xml b/hdl/vendor/AnalogDevices/+AnalogDevices/+util/ADIZynqSDRAttributeInfo.xml new file mode 100644 index 00000000..7c9a676b --- /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 100644 index 00000000..59654742 --- /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 100644 index 00000000..3df950a5 --- /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 100644 index 00000000..a600f581 --- /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/install.m b/hdl/vendor/AnalogDevices/+AnalogDevices/install.m new file mode 100644 index 00000000..9337a514 --- /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/uninstall.m b/hdl/vendor/AnalogDevices/+AnalogDevices/uninstall.m new file mode 100644 index 00000000..ce1a4337 --- /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 100644 index 00000000..a719fe9d --- /dev/null +++ b/hdl/vendor/AnalogDevices/Contents.m @@ -0,0 +1,2 @@ +% HDL Coder BSP: Analog Devices Inc +% Version 19.1.1 (R2019a) 5-September-2019 diff --git a/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m b/hdl/vendor/AnalogDevices/hdlcoder_board_customization.m new file mode 100644 index 00000000..062c3289 --- /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.daq2.zcu102.plugin_board', ... + }; +end +% LocalWords: Zynq ZC diff --git a/hsx_examples/daq2/daq2.m b/hsx_examples/daq2/daq2.m new file mode 100644 index 00000000..09a3e358 --- /dev/null +++ b/hsx_examples/daq2/daq2.m @@ -0,0 +1,30 @@ +% Test Tx DDS output +uri = 'ip:192.168.2.1'; + +%% Tx set up +tx = adi.DAQ2.Tx('uri',uri); +tx.DataSource = 'DDS'; +toneFreq = 45e6; +tx.DDSFrequencies = repmat(toneFreq,2,4); +tx(); + +%% Rx set up +rx = adi.DAQ2.Rx('uri',uri); + +%% Run +for k=1:10 + valid = false; + while ~valid + [out, valid] = rx(); + end +end +rx.release(); +tx.release(); + +%% Plot +nSamp = length(out); +fs = tx.SamplingRate; +FFTRxData = fftshift(10*log10(abs(fft(out)))); +df = fs/nSamp; freqRangeRx = (-fs/2:df:fs/2-df).'/1000; +plot(freqRangeRx, FFTRxData); +xlabel('Frequency (kHz)');ylabel('Amplitude (dB)');grid on; diff --git a/info.xml b/info.xml new file mode 100644 index 00000000..3c10476b --- /dev/null +++ b/info.xml @@ -0,0 +1,25 @@ + + + + + + + + + + R2019a + + Analog Devices, Inc. High Speed Converter Toolbox + + + toolbox + + + adi_logo.png + + doc + + + adi_logo.png + diff --git a/test/BSPInstallerTests.m b/test/BSPInstallerTests.m new file mode 100644 index 00000000..18b6dfdd --- /dev/null +++ b/test/BSPInstallerTests.m @@ -0,0 +1,49 @@ +classdef BSPInstallerTests < BSPTestsBase + properties + installed = []; + end + + methods(TestClassSetup) + function removeinstalledbsp(~) + str = 'Analog Devices'; + ts = matlab.addons.toolbox.installedToolboxes; + for t = ts + if contains(t.Name,str) + disp('Removing installed BSP'); + matlab.addons.toolbox.uninstallToolbox(t); + end + end + end + function installBSP(obj) + %system('wget https://github.com/analogdevicesinc/MathWorks_tools/releases/download/v18.1.0/AnalogDevicesBSP_v18.1.0.mltbx'); + %system('rm *.mltbx'); + %system('curl -s https://api.github.com/repos/analogdevicesinc/MathWorks_tools/releases/latest | grep browser_download_url | cut -d "\"" -f 4 | wget --no-check-certificate -i -'); + %tbname = 'AnalogDevicesBSP_v18.1.mltbx'; + disp('BSP Installer tests setup called'); + files = dir('.'); + for file = 1:length(files) + fn = files(file).name; + try + if strcmpi(fn(end-5:end),'.mltbx') && ~contains(fn,'examples') + tbname = fn; + break + end + catch + continue; + end + end + disp('BSP Installer tests setup called'); + disp(['Found: ',tbname]); + obj.installed = matlab.addons.toolbox.installToolbox(tbname); + obj.installed + disp("Installed"); + end + end + + methods(TestClassTeardown) + function uninstallBSP(obj) + matlab.addons.toolbox.uninstallToolbox(obj.installed); + end + end + +end diff --git a/test/BSPTests.m b/test/BSPTests.m new file mode 100644 index 00000000..2788d859 --- /dev/null +++ b/test/BSPTests.m @@ -0,0 +1,20 @@ +classdef BSPTests < BSPTestsBase + + methods(TestClassSetup) + function removeinstalledbsp(~) + str = 'Analog Devices'; + ts = matlab.addons.toolbox.installedToolboxes; + for t = ts + if contains(t.Name,str) + disp('Removing installed BSP'); + matlab.addons.toolbox.uninstallToolbox(t); + end + end + end + % Add the necessary files to path + function addbspfiles(~) + addpath(genpath('../hdl')); + end + end + +end diff --git a/test/BSPTestsBase.m b/test/BSPTestsBase.m new file mode 100644 index 00000000..c30b9a63 --- /dev/null +++ b/test/BSPTestsBase.m @@ -0,0 +1,209 @@ +classdef BSPTestsBase < matlab.unittest.TestCase + properties(TestParameter) + % Pull in board permutations + configs = board_variants; + ignored_builds = {''}; + SynthesizeDesign = {false}; + end + + properties + Count = 0; + TotalTests = 0; + Folder = pwd; + end + + methods(TestClassSetup) + function disableWarnings(~) + warning('off','hdlcommon:hdlcommon:InterfaceNotAssigned'); + end + function testCount(testCase) + testCase.TotalTests = length(testCase.configs); + CountS = 0; + save('tc.mat','CountS'); + end + function setRuntimeFolder(testCase) + testCase.Folder = tempname(pwd); + end + end + + methods(TestClassTeardown) + function enableWarnings(~) + warning('on','hdlcommon:hdlcommon:InterfaceNotAssigned'); + end + function collectLogs(~) + if ~exist([pwd,'/logs'],'dir') + mkdir('logs'); + end + system('cp *.log logs/'); + end + function collectBOOTBINs(~) + if ~exist([pwd,'/BINS'],'dir') + mkdir('BINS'); + end + system('cp *.BIN BINS/'); + end + end + + methods(TestMethodSetup) + function loadTestCount(testCase) + l = load('tc.mat'); + CountS = l.CountS + 1; + testCase.Count = CountS; + save('tc.mat','CountS'); + end + end + + + + methods + + function CollectBOOTBIN(testCase,cfgb) + rdn = strrep(cfgb.ReferenceDesignName,'/','_'); + rdn = strrep(rdn,'(',''); + rdn = strrep(rdn,')',''); + rdn = lower(rdn); + system(join(["find '",testCase.Folder,"' -name 'BOOT.BIN' | xargs -I '{}' cp {} ."],'')); + if exist('BOOT.BIN','file') + disp('Found BOOT.BIN... copying'); + movefile('BOOT.BIN',[rdn,'_BOOT_',cfgb.mode,'.BIN']); + end + end + + function CollectLogs(testCase,cfgb) + disp('Log collector called'); + rdn = strrep(cfgb.ReferenceDesignName,'/','_'); + rdn = strrep(rdn,'(',''); + rdn = strrep(rdn,')',''); + system(join(["find '",testCase.Folder,"' -name 'workflow_task_VivadoIPPackager.log' | xargs -I '{}' cp {} ."],'')); + if exist('workflow_task_VivadoIPPackager.log','file') + disp('Found workflow_task_VivadoIPPackager... copying'); + movefile('workflow_task_VivadoIPPackager.log',[rdn,'_VivadoIPPackager_',cfgb.mode,'.log']); + end + system(join(["find '",testCase.Folder,"' -name 'workflow_task_CreateProject.log' | xargs -I '{}' cp {} ."],'')); + if exist('workflow_task_CreateProject.log','file') + disp('Found workflow_task_CreateProject... copying'); + movefile('workflow_task_CreateProject.log',[rdn,'_CreateProject_',cfgb.mode,'.log']); + 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'); + movefile('workflow_task_BuildFPGABitstream.log',[rdn,'_BuildFPGABitstream_',cfgb.mode,'.log']); + end + end + + function cfg = ADRV9361_Variants(~,s) + + variants = {... + 'ccbob_cmos','ccbob_lvds',... + 'ccbox_lvds','ccfmc_lvds'}; + cfg = {}; + s = strjoin(s(1:end-2),'.'); + h1 = str2func([s,'.common.plugin_board']);h1 = h1(); + + for k = 1:length(variants) + + mode = 'rx'; + h2 = str2func([s,'.',variants{k},'.plugin_rd_rx']);h2 = h2(); + ReferenceDesignName = h2.ReferenceDesignName; + vivado_version = h2.SupportedToolVersion{:}; + cfg1 = struct('Board',h1,... + 'ReferenceDesignName',ReferenceDesignName,... + 'vivado_version',vivado_version,'mode',mode); + + mode = 'tx'; + h2 = str2func([s,'.',variants{k},'.plugin_rd_tx']);h2 = h2(); + ReferenceDesignName = h2.ReferenceDesignName; + vivado_version = h2.SupportedToolVersion{:}; + cfg2 = struct('Board',h1,... + 'ReferenceDesignName',ReferenceDesignName,... + 'vivado_version',vivado_version,'mode',mode); + + mode = 'rx_tx'; + h2 = str2func([s,'.',variants{k},'.plugin_rd_rxtx']);h2 = h2(); + ReferenceDesignName = h2.ReferenceDesignName; + vivado_version = h2.SupportedToolVersion{:}; + cfg3 = struct('Board',h1,... + 'ReferenceDesignName',ReferenceDesignName,... + 'vivado_version',vivado_version,'mode',mode); + cfg = [cfg(:)',{cfg1},{cfg2},{cfg3}]; + + end + + end + + + function cfg = extractConfigs(~,config) + s = strsplit(config,'.'); + modes = strsplit(s{end},'_'); + mode = modes{end}; + h1 = str2func(config);h1 = h1(); + + if strcmp(s{2},'adrv9361z7035') && ~isempty(strfind(s{2},'modem')) + assert(0); + elseif strcmp(s{2},'adrv9361z7035') || ... + strcmp(s{2},'adrv9364z7020') + h = str2func([strjoin(s(1:2),'.'),'.common.plugin_board']); + else + h = str2func([strjoin(s(1:end-1),'.'),'.plugin_board']); + end + board = h(); + + ReferenceDesignName = h1.ReferenceDesignName; + vivado_version = h1.SupportedToolVersion{:}; + cfg = struct('Board',board,... + 'ReferenceDesignName',ReferenceDesignName,... + 'vivado_version',vivado_version,'mode',mode); + end + + function setVivadoPath(~,vivado) + if ispc + pathname = ['C:\Xilinx\Vivado\',vivado,'\bin\vivado.bat']; + elseif isunix + pathname = ['/opt/Xilinx/Vivado/',vivado,'/bin/vivado']; + end + assert(exist(pathname,'file')>0,'Correct version of Vivado is unavailable or in a non-standard location'); + hdlsetuptoolpath('ToolName', 'Xilinx Vivado', ... + 'ToolPath', pathname); + pause(4); + end + end + + methods(Test) + function testMain(testCase, configs, SynthesizeDesign) + % Filter out ignored configurations + if ismember(configs,testCase.ignored_builds) + assumeFail(testCase); + end + % Extract board configuration + cfgb = testCase.extractConfigs(configs); + % for cfg = cfgs + if exist(testCase.Folder,'dir') + rmdir(testCase.Folder,'s'); + pause(1); + end + % Set up vivado + testCase.setVivadoPath(cfgb.vivado_version); + % Build + disp(repmat('/',1,80)); + disp(['Building: ',cfgb.Board.BoardName,' | ',cfgb.mode,... + ' (',num2str(testCase.Count),' of ',num2str(testCase.TotalTests),')']); + res = build_design(cfgb.Board,cfgb.ReferenceDesignName,... + cfgb.vivado_version,cfgb.mode,cfgb.Board.BoardName,... + SynthesizeDesign,testCase.Folder); + % Check + if isfield(res,'message') || isa(res,'MException') + disp(['Build error: ', cfgb.ReferenceDesignName]); + disp(res); + disp(res.message); + disp(res.stack); + testCase.CollectLogs(cfgb); + verifyEmpty(testCase,res,res.message); + else + if SynthesizeDesign + % Save BOOT.BIN + testCase.CollectBOOTBIN(cfgb); + end + end + end + end +end diff --git a/test/DAQ2Tests.m b/test/DAQ2Tests.m new file mode 100644 index 00000000..5e5a7afa --- /dev/null +++ b/test/DAQ2Tests.m @@ -0,0 +1,181 @@ +classdef DAQ2Tests < HardwareTests + + properties + uri = 'ip:analog'; + author = 'ADI'; + end + + methods(TestClassSetup) + % Check hardware connected + function CheckForHardware(testCase) + Device = @()adi.DAQ2.Rx; + testCase.CheckDevice('ip',Device,testCase.uri(4:end),false); + end + end + + methods (Static) + function estFrequency(data,fs) + nSamp = length(data); + FFTRxData = fftshift(10*log10(abs(fft(data)))); +% df = fs/nSamp; freqRangeRx = (-fs/2:df:fs/2-df).'/1000; +% plot(freqRangeRx, FFTRxData); + df = fs/nSamp; freqRangeRx = (0:df:fs/2-df).'/1000; + plot(freqRangeRx, FFTRxData(end-length(freqRangeRx)+1:end,:)); + end + + function freq = estFrequencyMax(data,fs) + nSamp = length(data); + FFTRxData = fftshift(10*log10(abs(fft(data)))); + df = fs/nSamp; freqRangeRx = (0:df:fs/2-df).'; + [~,ind] = max(FFTRxData(end-length(freqRangeRx)+1:end,:)); + freq = freqRangeRx(ind); + end + + end + + methods (Test) + + function testDAQ2Rx(testCase) + % Test Rx DMA data output + rx = adi.DAQ2.Rx('uri',testCase.uri); + rx.EnabledChannels = 1; + [out, valid] = rx(); + rx.release(); + testCase.verifyTrue(valid); + testCase.verifyGreaterThan(sum(abs(double(out))),0); + end + + function testDAQ2RxWithTxDDS(testCase) + % Test DDS output + tx = adi.DAQ2.Tx('uri',testCase.uri); + tx.DataSource = 'DDS'; + toneFreq = 45e6; + tx.DDSFrequencies = repmat(toneFreq,2,2); + tx(); + pause(1); + rx = adi.DAQ2.Rx('uri',testCase.uri); + rx.EnabledChannels = 1; + valid = false; + for k=1:10 + [out, valid] = rx(); + end + rx.release(); + +% plot(real(out)); +% testCase.estFrequency(out,rx.SamplingRate); + freqEst = meanfreq(double(real(out)),rx.SamplingRate); + + testCase.verifyTrue(valid); + testCase.verifyGreaterThan(sum(abs(double(out))),0); + testCase.verifyEqual(freqEst,toneFreq,'RelTol',0.01,... + 'Frequency of DDS tone unexpected') + end + + function testDAQ2RxWithTxDDSTwoChan(testCase) + % Test DDS output + tx = adi.DAQ2.Tx('uri',testCase.uri); + tx.DataSource = 'DDS'; + toneFreq1 = 160e6; + toneFreq2 = 300e6; + tx.DDSFrequencies = [toneFreq1,toneFreq2;toneFreq1,toneFreq2]; + tx.DDSScales = [1,1;0,0].*0.029; + tx(); + pause(1); + rx = adi.DAQ2.Rx('uri',testCase.uri); + rx.EnabledChannels = [1 2]; + valid = false; + for k=1:10 + [out, valid] = rx(); + end + rx.release(); + +% plot(real(out)); +% testCase.estFrequency(out,rx.SamplingRate); + freqEst1 = testCase.estFrequencyMax(out(:,1),rx.SamplingRate); + freqEst2 = testCase.estFrequencyMax(out(:,2),rx.SamplingRate); +% freqEst1 = meanfreq(double(real(out(:,1))),rx.SamplingRate); +% freqEst2 = meanfreq(double(real(out(:,2))),rx.SamplingRate); + + testCase.verifyTrue(valid); + testCase.verifyGreaterThan(sum(abs(double(out))),0); + testCase.verifyEqual(freqEst1,toneFreq1,'RelTol',0.01,... + 'Frequency of DDS tone unexpected') + testCase.verifyEqual(freqEst2,toneFreq2,'RelTol',0.01,... + 'Frequency of DDS tone unexpected') + end + + function testDAQ2RxWithTxData(testCase) + % Test Tx DMA data output + amplitude = 2^15; frequency = 40e6; + swv1 = dsp.SineWave(amplitude, frequency); + swv1.ComplexOutput = false; + swv1.SamplesPerFrame = 2^20; + swv1.SampleRate = 1e9; + y = swv1(); + + tx = adi.DAQ2.Tx('uri',testCase.uri); + tx.DataSource = 'DMA'; + tx.EnableCyclicBuffers = true; + tx(y); + rx = adi.DAQ2.Rx('uri',testCase.uri); + rx.EnabledChannels = 1; + for k=1:10 + [out, valid] = rx(); + end + rx.release(); + +% plot(real(out)); + freqEst = meanfreq(double(real(out)),rx.SamplingRate); + + testCase.verifyTrue(valid); + testCase.verifyGreaterThan(sum(abs(double(out))),0); + testCase.verifyEqual(freqEst,frequency,'RelTol',0.01,... + 'Frequency of ML tone unexpected') + end + + function testDAQ2RxWithTxDataTwoChan(testCase) + % Test Tx DMA data output + amplitude = 2^15; toneFreq1 = 40e6; + swv1 = dsp.SineWave(amplitude, toneFreq1); + swv1.ComplexOutput = false; + swv1.SamplesPerFrame = 2^20; + swv1.SampleRate = 1e9; + y1 = swv1(); + + amplitude = 2^15; toneFreq2 = 180e6; + swv1 = dsp.SineWave(amplitude, toneFreq2); + swv1.ComplexOutput = false; + swv1.SamplesPerFrame = 2^20; + swv1.SampleRate = 1e9; + y2 = swv1(); + + tx = adi.DAQ2.Tx('uri',testCase.uri); + tx.DataSource = 'DMA'; + tx.EnableCyclicBuffers = true; + tx.EnabledChannels = [1,2]; + tx([y1,y2]); + rx = adi.DAQ2.Rx('uri',testCase.uri); + rx.EnabledChannels = [1,2]; + for k=1:10 + [out, valid] = rx(); + end + rx.release(); + +% plot(real(out)); +% testCase.estFrequency(out,rx.SamplingRate); + freqEst1 = testCase.estFrequencyMax(out(:,1),rx.SamplingRate); + freqEst2 = testCase.estFrequencyMax(out(:,2),rx.SamplingRate); +% freqEst = meanfreq(double(real(out)),rx.SamplingRate); + + testCase.verifyTrue(valid); + testCase.verifyGreaterThan(sum(abs(double(out))),0); + testCase.verifyEqual(freqEst1,toneFreq1,'RelTol',0.01,... + 'Frequency of DDS tone unexpected') + testCase.verifyEqual(freqEst2,toneFreq2,'RelTol',0.01,... + 'Frequency of DDS tone unexpected') + end + + end + +end + diff --git a/test/HardwareTests.m b/test/HardwareTests.m new file mode 100644 index 00000000..ee25e20b --- /dev/null +++ b/test/HardwareTests.m @@ -0,0 +1,40 @@ +classdef HardwareTests < matlab.unittest.TestCase + + properties (Abstract) + author + uri + end + + methods + % Check hardware connected + function CheckDevice(testCase,type,Dev,ip,istx) + try + switch type + case 'usb' + d = Dev(); + case 'ip' + if strcmp(testCase.author,'MathWorks') + d= Dev(); + d.IPAddress = ip; + else + d= Dev(); + d.uri = ['ip:',ip]; + end + otherwise + error('Unknown interface type'); + end + if istx + d(complex(randn(1024,1),randn(1024,1))); + else + d(); + end + + catch ME + disp(ME.message); + assumeFail(testCase,'Filtering test: No device found'); + end + end + + end + +end \ No newline at end of file diff --git a/test/board_variants.m b/test/board_variants.m new file mode 100644 index 00000000..7c1fd5de --- /dev/null +++ b/test/board_variants.m @@ -0,0 +1,16 @@ +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 2012-2013 The MathWorks, Inc. + +r = { ... + 'AnalogDevices.daq2.zcu102.plugin_rd_rx', ... + 'AnalogDevices.daq2.zcu102.plugin_rd_tx' ... + }; +end +% LocalWords: Zynq ZC diff --git a/test/build_design.m b/test/build_design.m new file mode 100644 index 00000000..39e016e2 --- /dev/null +++ b/test/build_design.m @@ -0,0 +1,81 @@ + +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; + +% 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); + 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/runHWTests.m b/test/runHWTests.m new file mode 100644 index 00000000..98cbc55c --- /dev/null +++ b/test/runHWTests.m @@ -0,0 +1,30 @@ +import matlab.unittest.TestRunner; +import matlab.unittest.TestSuite; +import matlab.unittest.plugins.TestReportPlugin; +import matlab.unittest.plugins.XMLPlugin + +try + suite = testsuite({'DAQ2Tests'}); + runner = TestRunner.withNoPlugins; + xmlFile = 'HWTestResults.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(['BSPTest_',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 00000000..88570025 --- /dev/null +++ b/test/runSynthTests.m @@ -0,0 +1,35 @@ +import matlab.unittest.TestRunner; +import matlab.unittest.TestSuite; +import matlab.unittest.plugins.TestReportPlugin; +import matlab.unittest.plugins.XMLPlugin +import matlab.unittest.parameters.Parameter + +SynthesizeDesign = {true}; + +param = Parameter.fromData('SynthesizeDesign',SynthesizeDesign); + +try + suite = TestSuite.fromClass(?BSPTests,'ExternalParameters',param); + runner = TestRunner.withNoPlugins; + xmlFile = 'BSPSynthTestResults.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(['BSPTest_',datestr(now,'dd_mm_yyyy-HH:MM:SS'),'.mat'],'t'); +bdclose('all'); +exit(any([results.Failed])); diff --git a/test/runTests.m b/test/runTests.m new file mode 100644 index 00000000..d80313bf --- /dev/null +++ b/test/runTests.m @@ -0,0 +1,70 @@ +function runTests(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 = {false}; +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',1); + runner.addPlugin(DiagnosticsValidationPlugin) + + xmlFile = 'BSPTestResults.xml'; + plugin = XMLPlugin.producingJUnitFormat(xmlFile); + runner.addPlugin(plugin); + + if runParallel + try %#ok + parpool(2); + 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 + if runParallel + poolobj = gcp('nocreate'); + delete(poolobj); + end +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 00000000..ee367670 --- /dev/null +++ b/test/setportmapping.m @@ -0,0 +1,114 @@ +function mdl = setportmapping(mode,ReferenceDesignName,board_name) + +%mdl = 'testModel'; +numChannels = 2; + +if mod(numChannels,2)~=0 + error('Channels must be multiple of 2'); +end + +if contains(lower(ReferenceDesignName),'daq2') + dev = 'DAQ2'; + mdl = 'testModel_Rx64Tx64'; + portWidthRX = 64; + portWidthTX = 64; +else + error('Unknown device'); +end + +load_system(mdl); + + +% First set all ports to NIS +for k=1:8 + 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 + + +switch mode + case 'tx' + hdlset_param([mdl,'/HDL_DUT/in1'], 'IOInterface', ['DMA Data 0 IN [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in1'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in2'], 'IOInterface', ['DMA Data 1 IN [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in2'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + + hdlset_param([mdl,'/HDL_DUT/out1'], 'IOInterface', [dev,' DAC Data 0 OUT [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out1'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out2'], 'IOInterface', [dev,' DAC Data 1 OUT [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out2'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + if numChannels==4 + hdlset_param([mdl,'/HDL_DUT/in3'], 'IOInterface', ['DMA Data 2 IN [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in3'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in4'], 'IOInterface', ['DMA Data 3 IN [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in4'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out3'], 'IOInterface', [dev,' DAC Data 2 [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out3'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out4'], 'IOInterface', [dev,' DAC Data 3 [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out4'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + end + case 'rx' + hdlset_param([mdl,'/HDL_DUT/in1'], 'IOInterface', [dev,' ADC Data 0 IN [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in1'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in2'], 'IOInterface', [dev,' ADC Data 1 IN [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in2'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out1'], 'IOInterface', ['IP Data 0 OUT [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out1'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out2'], 'IOInterface', ['IP Data 1 OUT [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out2'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + if numChannels==4 + hdlset_param([mdl,'/HDL_DUT/in3'], 'IOInterface', [dev,' ADC Data 2 IN [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in3'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in4'], 'IOInterface', [dev,' ADC Data 3 IN [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in4'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out3'], 'IOInterface', ['IP Data 2 OUT [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out3'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out4'], 'IOInterface', ['IP Data 3 OUT [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out4'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + end + case 'rxtx' + % RX + hdlset_param([mdl,'/HDL_DUT/in1'], 'IOInterface', [dev,' ADC Data 0 [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in1'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in2'], 'IOInterface', [dev,' ADC Data 1 [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in2'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out1'], 'IOInterface', ['IP Data 0 OUT [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out1'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out2'], 'IOInterface', ['IP Data 1 OUT [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out2'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + % TX + hdlset_param([mdl,'/HDL_DUT/in3'], 'IOInterface', ['DMA Data 0 IN [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in3'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in4'], 'IOInterface', ['DMA Data 1 IN [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in4'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out3'], 'IOInterface', [dev,' DAC Data 0 OUT [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out3'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out4'], 'IOInterface', [dev,' DAC Data 1 OUT [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out4'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + + + if numChannels==4 + hdlset_param([mdl,'/HDL_DUT/in5'], 'IOInterface', [dev,' ADC Data 2 IN [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in5'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in6'], 'IOInterface', [dev,' ADC Data 3 IN [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in6'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out5'], 'IOInterface', ['DMA Data 2 OUT [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out5'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out6'], 'IOInterface', ['DMA Data 3 OUT [0:',num2str(portWidthRX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out6'], 'IOInterfaceMapping', ['[0:',num2str(portWidthRX-1),']']); + + hdlset_param([mdl,'/HDL_DUT/in7'], 'IOInterface', ['DMA Data 2 IN [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in7'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in8'], 'IOInterface', ['DMA Data 3 IN [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/in8'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out7'], 'IOInterface', [dev,' DAC Data 2 OUT [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out7'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out8'], 'IOInterface', [dev,' DAC Data 3 OUT [0:',num2str(portWidthTX-1),']']); + hdlset_param([mdl,'/HDL_DUT/out8'], 'IOInterfaceMapping', ['[0:',num2str(portWidthTX-1),']']); + end + + otherwise + error('Unknown mode'); +end diff --git a/test/testModel_Rx64Tx64.slx b/test/testModel_Rx64Tx64.slx new file mode 100644 index 00000000..f2779d5b Binary files /dev/null and b/test/testModel_Rx64Tx64.slx differ