Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 58 additions & 16 deletions +adi/+AD9081/Base.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,23 +129,29 @@
idx = idx(idx2);
filteredMap{end+1} = map{idx};
end
% Count unique items with XDUCX
% Count unique coarse (CDUC/CDDC) and fine (FDUC/FDDC) data
% converters. filteredMap holds one entry per unique fine
% path, so several fine paths can share a single coarse
% converter (e.g. FDUC1/2/3 all feeding CDUC0). Counting
% raw occurrences therefore overestimates the coarse count;
% track which converter indices are present instead.
if isTx
ss = 'U';
else
ss = 'D';
end
numFDUCX = 0; numCDUCX = 0;
finePresent = false(1,8); coarsePresent = false(1,8);
for DC = 0:7
for k=1:length(filteredMap)
if contains(filteredMap{k},sprintf('FD%sC%d',ss,DC))
numFDUCX = numFDUCX + 1;
finePresent(DC+1) = true;
end
if contains(filteredMap{k},sprintf('CD%sC%d',ss,DC))
numCDUCX = numCDUCX + 1;
coarsePresent(DC+1) = true;
end
end
end
numFDUCX = sum(finePresent); numCDUCX = sum(coarsePresent);
num_coarse = numCDUCX; num_fine = numFDUCX; num_data = numFDUCX*2;
if ~doNotCloseConnection
obj.releaseImpl();
Expand All @@ -171,10 +177,8 @@ function CheckAndUpdateHW(obj, value, name, attr, phy, output)
end
if contains(attr,'channel_')
N = obj.num_fine_attr_channels;
stride = 1;
elseif contains(attr,'main_')
N = obj.num_coarse_attr_channels;
stride = obj.num_fine_attr_channels/N;
else
error('Unknown attribute name');
end
Expand All @@ -185,9 +189,9 @@ function CheckAndUpdateHW(obj, value, name, attr, phy, output)
assert(c1 && c2,...
sprintf('%s expected to be at most size [1x%d]',name,N));
if obj.ConnectedToDevice
ids = obj.getAttributeChannelIDs(attr, phy, output, N);
for k=1:N
id = sprintf('voltage%d_i',(k-1)*stride);
obj.setAttributeLongLong(id,attr,value(k),output, tol, phy);
obj.setAttributeLongLong(ids{k},attr,value(k),output, tol, phy);
end
end
end
Expand All @@ -198,10 +202,8 @@ function CheckAndUpdateHWFloat(obj, value, name, attr, phy, output)
end
if contains(attr,'channel_')
N = obj.num_fine_attr_channels;
stride = 1;
elseif contains(attr,'main_')
N = obj.num_coarse_attr_channels;
stride = obj.num_fine_attr_channels/N;
else
error('Unknown attribute name');
end
Expand All @@ -212,9 +214,9 @@ function CheckAndUpdateHWFloat(obj, value, name, attr, phy, output)
assert(c1 && c2,...
sprintf('%s expected to be at most size [1x%d]',name,N));
if obj.ConnectedToDevice
ids = obj.getAttributeChannelIDs(attr, phy, output, N);
for k=1:N
id = sprintf('voltage%d_i',(k-1)*stride);
obj.setAttributeDouble(id,attr,value(k),output, tol, phy);
obj.setAttributeDouble(ids{k},attr,value(k),output, tol, phy);
end
end
end
Expand All @@ -225,10 +227,8 @@ function CheckAndUpdateHWBool(obj, value, name, attr, phy, output)
end
if contains(attr,'channel_') || strcmpi(attr,'en')
N = obj.num_fine_attr_channels;
stride = 1;
elseif contains(attr,'main_')
N = obj.num_coarse_attr_channels;
stride = obj.num_fine_attr_channels/N;
else
error('Unknown attribute name');
end
Expand All @@ -238,13 +238,48 @@ function CheckAndUpdateHWBool(obj, value, name, attr, phy, output)
assert(c1 && c2,...
sprintf('%s expected to be at most size [1x%d]',name,N));
if obj.ConnectedToDevice
ids = obj.getAttributeChannelIDs(attr, phy, output, N);
for k=1:N
id = sprintf('voltage%d_i',(k-1)*stride);
obj.setAttributeBool(id,attr,value(k),output, phy);
obj.setAttributeBool(ids{k},attr,value(k),output, phy);
end
end
end

function ids = getAttributeChannelIDs(obj, attr, phy, output, N)
% Resolve the physical voltage channel IDs used to write an
% attribute. Fine (channel_*) attributes map directly to
% voltage0_i..voltage(N-1)_i. Coarse (main_*) attributes are
% only exposed on the subset of physical channels that own a
% coarse data converter; on some HDL datapaths several fine
% channels share a coarse converter, so the coarse-capable
% channels are not contiguous. Probe readability to select
% them robustly instead of assuming a fixed stride.
if contains(attr,'main_')
ids = obj.getReadableAttributeChannelIDs(attr, phy, output, N);
else
ids = obj.getFineAttributeChannelIDs(N);
end
end

function ids = getFineAttributeChannelIDs(~, N)
ids = cell(1, N);
for k = 1:N
ids{k} = sprintf('voltage%d_i', k-1);
end
end

function ids = getReadableAttributeChannelIDs(obj, attr, phy, output, N)
candidateIDs = obj.getFineAttributeChannelIDs(obj.max_num_fine_attr_channels);
readLengths = -ones(1, numel(candidateIDs));
for k = 1:numel(candidateIDs)
chanPtr = iio_device_find_channel(obj, phy, candidateIDs{k}, output);
if cPtrCheck(obj, chanPtr) == 0
[readLengths(k), ~] = iio_channel_attr_read(obj, chanPtr, attr, 1024);
end
end
ids = obj.selectReadableAttributeChannelIDs(candidateIDs, readLengths, N);
end

function attr = iio_channel_is_output(obj, chanPtr)
% iio_channel_is_output(const struct iio_channel *chn)
%
Expand All @@ -256,6 +291,13 @@ function CheckAndUpdateHWBool(obj, value, name, attr, phy, output)

end

methods (Static, Hidden)
function ids = selectReadableAttributeChannelIDs(candidateIDs, readLengths, N)
ids = adi.AD9081.selectReadableAttributeChannelIDs( ...
candidateIDs, readLengths, N);
end
end

%% External Dependency Methods
methods (Hidden, Static)

Expand Down
23 changes: 20 additions & 3 deletions +adi/+AD9081/Tx.m
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,31 @@
function set.DDROffloadEnable(obj, value)
obj.DDROffloadEnable = value;
if obj.ConnectedToDevice
obj.setDebugAttributeBool('pl_ddr_fifo_enable',value, true, obj.iioDev);
obj.setDDROffloadEnableIfSupported(value);
end
end
end

%% API Functions
methods (Hidden, Access = protected)

function setDDROffloadEnableIfSupported(obj, value)
% The pl_ddr_fifo_enable debug attribute controls the PL DDR
% transmit FIFO offload. It is only present on HDL datapaths
% that instantiate the DDR offload block; newer AD9081
% reference designs (e.g. hdl_2026_r1 m8_l4) omit it. Probe
% for the attribute and skip the write when it is absent so
% streaming still works on both datapath variants.
if obj.hasDebugAttribute('pl_ddr_fifo_enable', obj.iioDev)
obj.setDebugAttributeBool('pl_ddr_fifo_enable', value, ...
true, obj.iioDev);
end
end

function tf = hasDebugAttribute(obj, attr, dev)
[nBytes, ~] = obj.iio_device_debug_attr_read(dev, attr, 1024);
tf = nBytes >= 0;
end

function setupImpl(obj, data)
if strcmp(obj.DataSource,'DMA')
Expand Down Expand Up @@ -206,8 +224,7 @@ function setupInit(obj)
if strcmp(obj.DataSource,'DDS')
obj.DDSUpdate();
else
obj.setDebugAttributeBool('pl_ddr_fifo_enable',...
obj.DDROffloadEnable, false, obj.iioDev);
obj.setDDROffloadEnableIfSupported(obj.DDROffloadEnable);
end
end

Expand Down
21 changes: 21 additions & 0 deletions +adi/+AD9081/selectReadableAttributeChannelIDs.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function ids = selectReadableAttributeChannelIDs(candidateIDs, readLengths, N)
%selectReadableAttributeChannelIDs Choose coarse-capable AD9081 channel IDs
% IDS = selectReadableAttributeChannelIDs(CANDIDATEIDS, READLENGTHS, N)
% returns the first N channel IDs from CANDIDATEIDS whose corresponding
% READLENGTHS entry is positive (i.e. the coarse attribute read back a
% value rather than returning an error). On the AD9081 hdl_2026_r1
% datapath, main_* (coarse) attributes are exposed on only a subset of
% the physical voltage channels, and those channels are not contiguous,
% so channel selection must be driven by attribute readability rather
% than a fixed stride.
%
% This is a plain package function (no libiio superclass dependency) so
% the selection logic can be unit tested without the libiio hardware
% support package installed.
assert(numel(candidateIDs) == numel(readLengths), ...
'Candidate IDs and read lengths must have equal size');
ids = candidateIDs(readLengths > 0);
assert(numel(ids) >= N, ...
'Not enough channels expose the requested AD9081 attribute');
ids = ids(1:N);
end
2 changes: 1 addition & 1 deletion +adi/+common
Submodule +common updated 1 files
+1 −1 Debug.m
36 changes: 36 additions & 0 deletions +adi/+sim/+common/DelayLine.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
classdef DelayLine < matlab.System
%DelayLine Frame-based streaming delay independent of dsp.DelayLine.
properties (Nontunable)
Length (1,1) {mustBeInteger,mustBeNonnegative} = 1
end

properties (DiscreteState, Hidden)
State
end

methods
function obj = DelayLine(varargin)
setProperties(obj, nargin, varargin{:});
end
end

methods (Access = protected)
function setupImpl(obj, input)
obj.State = zeros(obj.Length, size(input, 2), 'like', input);
end

function output = stepImpl(obj, input)
if obj.Length == 0
output = input;
return;
end
buffered = [obj.State; input];
output = buffered(1:size(input, 1), :);
obj.State = buffered(end-obj.Length+1:end, :);
end

function resetImpl(obj)
obj.State(:) = 0;
end
end
end
7 changes: 5 additions & 2 deletions +adi/+sim/+common/PFilter.m
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function setupImpl(obj)
end
end

obj.DelayLine = dsp.DelayLine('Length',tapGroups*4);
obj.DelayLine = adi.sim.common.DelayLine('Length',tapGroups*4);
end

function [z1,z2] = stepImpl(obj,u1,u2)
Expand Down Expand Up @@ -268,7 +268,10 @@ function setupImpl(obj)
end

function resetImpl(obj)
% Initialize / reset discrete-state properties
for filter = 1:numel(obj.Filters)
reset(obj.Filters{filter});
end
reset(obj.DelayLine);
end
end
end
8 changes: 4 additions & 4 deletions +adi/Version.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
%Version
% BSP Version information
properties(Constant)
HDL = 'hdl_2022_r2';
Vivado = '2022.2';
MATLAB = 'R2023b';
Release = '23.2.1';
HDL = 'hdl_2026_r1';
Vivado = '2025.1';
MATLAB = 'R2025b';
Release = '25.2.1';
AppName = 'Analog Devices, Inc. High-Speed Converter Toolbox';
ToolboxName = 'HighSpeedConverterToolbox';
ToolboxNameShort = 'hsx';
Expand Down
8 changes: 2 additions & 6 deletions .github/doc/scripts/get_styles.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
get_style () {
echo "Installing $2 from $1 ..."
curl -s https://api.github.com/repos/$1/$2/releases/latest \
| grep "browser_download_url.*zip" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -qi -
unzip $2.zip -d styles && rm -rf $2.zip
wget -q "https://github.com/vale-cli/$2/releases/latest/download/$2.zip"
unzip -q "$2.zip" -d styles && rm -f "$2.zip"
}

#styles=( Microsoft )
Expand Down
24 changes: 17 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,35 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Python 3.10
uses: actions/setup-python@v2
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '3.12'
- name: Test release metadata helpers
run: python -m unittest CI.scripts.test_get_required_vivado_version
- name: Organize Toolbox Dependencies
run: |
make -C ./CI/scripts build
pip3 install -r CI/gen_doc/requirements_doc.txt
make -C CI/gen_doc doc

- name: Set up MATLAB
uses: matlab-actions/setup-matlab@v1
uses: matlab-actions/setup-matlab@v2
with:
release: R2023b
release: R2025b
products: DSP_System_Toolbox Fixed-Point_Designer
- name: Test MATLAB R2025b compatibility
uses: matlab-actions/run-command@v2
with:
command: >-
addpath(pwd); addpath(fullfile(pwd,'test'));
results = runtests({'test/ReleaseCompatibilityTests.m',
'test/R2025bCompatibilityTests.m'}); assertSuccess(results)
- name: Compile Toolbox
uses: matlab-actions/run-command@v1
uses: matlab-actions/run-command@v2
with:
command: cd('CI/scripts');genTlbx(1);exit()

Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.9
uses: actions/setup-python@v2
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.9
python-version: 3.12

- name: Install dependencies
run: |
Expand All @@ -23,7 +23,7 @@ jobs:

- name: Publish master doc
if: github.ref == 'refs/heads/master'
uses: peaceiris/actions-gh-pages@v3
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./doc
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/vale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ jobs:
Vale:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.12'
architecture: x64
- name: Install dependencies
run: |
Expand Down
Loading
Loading