Skip to content

Initial vx4 port for SSRC and ASRC and async FIFO - #162

Open
ed-xmos wants to merge 6 commits into
xmos:developfrom
ed-xmos:feature/vx4_port
Open

ed-xmos wants to merge 6 commits into
xmos:developfrom
ed-xmos:feature/vx4_port

Conversation

@ed-xmos

@ed-xmos ed-xmos commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Second of many PRs for https://xmosjira.atlassian.net/browse/UA-1287
This does the bulk of the VX4b work for MRHF.

Still lots to go including Bob support and other filters.

@ed-xmos ed-xmos self-assigned this Nov 10, 2026
@ed-xmos
ed-xmos force-pushed the feature/vx4_port branch 4 times, most recently from 6d0bedb to 473521f Compare November 11, 2026 16:19
@ed-xmos ed-xmos changed the title vx4 port Initial vx4 port for SSRC and ASRC Nov 11, 2026
ed-xmos and others added 5 commits November 13, 2026 12:39
Add vx4 to jenkins and refresh deps
Bump python deps
Promote VX4 (xcore-400) VPU ASRC inner loops into lib_src

- Move the VPU implementations of the four multirate HiFi inner loops
  (adfir, fir, fir_os, spline coeff gen) from the asrc_vx4_test app into
  lib_src/src/multirate_hifi/src_mrhf_inner_loops_asm_vx4b.S, guarded by
  __VX4B__.
- Default SRC_USE_VPU to 1 on VX4 in use_vpu.h so the VPU data layouts
  and *_xs3 entry points are selected automatically, and drop the
  explicit -DSRC_USE_VPU=1 from the test app.
- Pack the reduce epilogues where the instruction set allows (vlsat and
  mkmski cannot be packeted).
- Remove xscope from the vx4 test app; it brings no benefit under xsim
  and plain prints are visible directly on the simulator console.

Self-test under xsim: all unit tests and ASRC rate cases pass, inner
loop speedups of 14.7-16.7x and whole-ASRC speedups of 2.3-2.9x vs the
scalar reference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Add VX4 scalar fallbacks to lib_src and SSRC self-test coverage

- Add src_mrhf_inner_loops_scalar_vx4b.c: portable C implementations of
  the plain (non-VPU) multirate HiFi inner loops for VX4 (xcore-400).
  These are required by the PPFIR polyphase path (SSRC 44.1k<->48k
  family) and ADFIR_proc_macc, which have no VPU dispatch, and serve as
  the reference implementations for the architecture self-tests.
- Guard the XS2/XS3 dual-issue assembly inner loops (and dither maths)
  with !defined(__VX4B__) so a VX4 library build does not attempt to
  assemble xcore instructions.
- Move the scalar reference implementations out of the asrc_vx4_test app
  (now provided by the library) and drop the vx4_mul_s32 asm helper.
- Add unit_test_ssrc to the shared VPU self-test: 44.1kHz -> 48kHz sine
  conversion against a golden reference generated by the double-precision
  host model, exercising PPFIR + OS2 FIR paths that the ASRC cases never
  touch. Runs on both xs3a and vx4b profiles.

Verified under xsim: vx4b (XTC 0.3.7) and xs3a (XTC 15.3.1) self-tests
both PASS with 0 errors, including the new SSRC case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Rename XS3 VPU inner loops file to match the VX4 naming

src_mrhf_adfir_inner_loop_asm_xs3.S contained all four VPU inner loops
(adfir, fir, fir_os and spline coeff gen), not just adfir.  Rename it to
src_mrhf_inner_loops_asm_xs3.S so it sits symmetrically alongside
src_mrhf_inner_loops_asm_vx4b.S, and add a descriptive header.  No
symbol or build changes; lib sources are auto-discovered.

Verified: xs3a (XTC 15.3.1) and vx4b (XTC 0.3.7) self-tests both PASS.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Document the VPU and scalar inner loop source files for both xcore.ai
  and xcore-400 in the multi-rate HiFi code structure section, including
  use_vpu.h and the renamed src_mrhf_inner_loops_asm_xs3.S
- Note VPU acceleration on xcore-400 in the introduction and in the
  SSRC/ASRC resource usage tips
- Add changelog entries for the scalar C fallbacks, the SSRC self-test
  case and the VPU file rename

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Port async fifo to vx4b
@ed-xmos ed-xmos changed the title Initial vx4 port for SSRC and ASRC Initial vx4 port for SSRC and ASRC and async FIFO Nov 13, 2026
@ed-xmos
ed-xmos requested review from Allan-xmos and xalbertoisorna and a balanced review from Copilot and removed request for Copilot November 13, 2026 12:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved VX4 assembly and FIFO memory-ordering defects can prevent builds or corrupt samples, while signed-overflow bugs undermine scalar processing and test reliability.

4 open issues
What changed in this PR

This PR adds initial xcore-400 (VX4) support to the library’s synchronous and asynchronous sample-rate converters and asynchronous FIFO.

Changes:

  • Adds VX4 vector kernels and scalar fallbacks, with shared VPU entry-point names.
  • Extends architecture self-tests and Jenkins coverage, including a golden-reference SSRC conversion.
  • Updates target selection, Python dependency pins, and architecture documentation.
File Description
tests/​sim_tests/​test_mrhf.py Builds and runs architecture-specific self-tests.
tests/​sim_tests/​asrc_vpu_test/​src/​vx4/​timer.h Declares the VX4 delay helper.
tests/​sim_tests/​asrc_vpu_test/​src/​test_asrc_vpu.c Adds portable timing, SSRC coverage, and failure exit status.
tests/​sim_tests/​asrc_vpu_test/​src/​asrc_vx4_asm.c Implements delays using Basix.
tests/​sim_tests/​asrc_vpu_test/​CMakeLists.txt Adds VX4 self-test build configuration.
tests/​setup.py Updates test dependency pins.
tests/​requirements.txt Updates test tooling pins.
python/​setup.py Updates Python package dependencies.
lib_src/​src/​multirate_hifi/​use_vpu.h Enables VPU processing by default on VX4.
lib_src/​src/​multirate_hifi/​src_mrhf_spline_coeff_gen_inner_loop_asm.S Excludes legacy spline assembly on VX4.
lib_src/​src/​multirate_hifi/​src_mrhf_spline_coeff_gen_inner_loop_asm.h Declares the shared VPU spline entry point.
lib_src/​src/​multirate_hifi/​src_mrhf_inner_loops_scalar_vx4b.c Adds VX4 scalar inner-loop implementations.
lib_src/​src/​multirate_hifi/​src_mrhf_inner_loops_asm_xs3.S Renames XS3 entry points to shared VPU names.
lib_src/​src/​multirate_hifi/​src_mrhf_inner_loops_asm_vx4b.S Adds VX4 VPU inner-loop kernels.
lib_src/​src/​multirate_hifi/​src_mrhf_fir.c Uses shared VPU calls and adds eligible polyphase dispatch.
lib_src/​src/​multirate_hifi/​src_mrhf_fir_os_inner_loop_asm.S Excludes legacy oversampling assembly on VX4.
lib_src/​src/​multirate_hifi/​src_mrhf_fir_os_inner_loop_asm.h Declares the shared oversampling VPU entry point.
lib_src/​src/​multirate_hifi/​src_mrhf_fir_inner_loop_asm.S Excludes legacy FIR assembly on VX4.
lib_src/​src/​multirate_hifi/​src_mrhf_fir_inner_loop_asm.h Declares the shared FIR VPU entry point.
lib_src/​src/​multirate_hifi/​src_mrhf_dither_maths_asm.S Excludes legacy dither assembly on VX4.
lib_src/​src/​multirate_hifi/​src_mrhf_adfir_inner_loop_asm.S Excludes legacy adaptive FIR assembly on VX4.
lib_src/​src/​multirate_hifi/​src_mrhf_adfir_inner_loop_asm.h Declares the shared adaptive FIR VPU entry point.
lib_src/​src/​multirate_hifi/​asrc/​src_mrhf_asrc.c Uses the shared spline VPU entry point.
lib_src/​src/​multirate_hifi/​asrc/​src_mrhf_asrc_wrapper.c Uses shared spline and adaptive FIR VPU calls.
lib_src/​src/​asynchronous_fifo.c Adds VX4 producer and consumer copy branches.
Jenkinsfile Builds and runs the VX4 self-test with Slipgate.
examples/​app_asynchronous_fifo/​CMakeLists.txt Allows hardware-target overrides.
examples/​app_asynchronous_fifo/​asynchronous_fifo/​CMakeLists.txt Allows hardware-target overrides for the nested app.
doc/​rst/​resource_usage_ssrc.rst Extends VPU performance guidance to xcore-400.
doc/​rst/​resource_usage_asrc.rst Extends ASRC performance guidance to xcore-400.
doc/​rst/​multi_rate_hifi_src.rst Documents architecture selection and kernel implementations.
doc/​rst/​introduction.rst Notes VPU acceleration on supported architectures.
doc/​python/​requirements.txt Updates documentation tooling pins.
CHANGELOG.rst Records VX4 support and self-test additions.
.gitignore Ignores generated test and performance CSV reports.

Review effort: Balanced

Comment on lines +138 to +139
asm("xm.vldr %0[0]" :: "r" (ptr));
asm("xm.vstrpv %0[0], %1" :: "r" (state->buffer + write_ptr * channel_count), "r" (copy_mask));
Comment on lines +138 to +139
asm("xm.vldr %0[0]" :: "r" (ptr));
asm("xm.vstrpv %0[0], %1" :: "r" (state->buffer + write_ptr * channel_count), "r" (copy_mask));
Comment on lines +76 to +88
int64_t accumulators[2] = {0, 0};
unsigned iterations = (unsigned)count >> 2;

for (unsigned iteration = 0; iteration < iterations; ++iteration) {
for (unsigned sample = 0; sample < 8; ++sample) {
unsigned data_index = iteration * 8 + sample;
unsigned coef_index = iteration * 16 + sample * 2;
accumulators[0] += (int64_t)data[data_index] * coefs[coef_index];
accumulators[1] += (int64_t)data[data_index] * coefs[coef_index + 1];
}
}
result[0] = saturate_shift(accumulators[0], 31);
result[1] = saturate_shift(accumulators[1], 31);
ASRC_TEST_GETTIME(t1);
total_time += t1 - t0;
for (unsigned j = 0; j < n_samps_out; j++) {
if (abs(out_samples[j] - expected_ssrc_44_48[exp_cnt]) > 25) {

@xalbertoisorna xalbertoisorna left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Ed, I haven't had a chance to go through everything yet, but here are some initial quick comments, Ill continue reviewing next week:

  • I'd suggest adding Pavel, who has mainly contributed to lib_src. I haven't worked with it before, so his input would be particularly valuable for the assembly review.
  • Would it be possible to use a more generic term like "xcore devices" rather than repeatedly mentioning "xcore.ai" / "xcore-400"? Alternatively, perhaps "xcore and RISC-V xcore" ? not sure. Something a bit more agnostic would be preferable.
  • I'd define __VX4B__ in src.h if it's not already defined, in preparation for vx-clang.
  • I agree with Copilot regarding asm("xm.vldr %0[0]"...). This doesn't seem correct for VX4, which also makes me wonder about our CI/CD coverage.
  • I wouldn't use xm.gettime when we already have get_reference_time() provided by lib_xcore. lib_basix also has its own call.
  • Instead of manually invoking cmake, I'd try to rely on xcorebuild().
  • I think XCC_TARGET_PATH is not needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants