Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Default builds can fail, and multiple optimized volume, EQ, and mixer paths currently produce invalid or misrouted audio.
15 open findings
Produce high-aligned S32 output in 16-bit fallback paths · New Handle all supported input channel geometries · New Restrict ESP32-P4-specific SIMD dependency to ESP32-P4 targets · New Fix missing default float API and state integration · New Use 64-bit accumulation for parallel biquad branches · New Prevent Q1.31 rounding overflow before S16 conversion · New Prevent int32 overflow during rounded S24 conversion · New Derive 5.1 output order from the configured channel map · New Widen IPC3 gain multiplication before saturation · New Restrict PIE conversion to Q8.16 sub-unity gains · New Clamp widened result before narrowing to S24 · New Include math.h for fabsf declaration · New Prevent overflow in IPC3 gain multiplication · New Clamp IPC3 result before narrowing to int32 · New Add RISC-V defaults to the active Kconfig choice · New
What changed in this PR
Adds RISC-V-optimized audio processing kernels and ESP32-P4 PIE SIMD support.
Changes:
- Adds RISC-V IIR, EQ, DRC, volume, mixer, FIR, and conversion paths.
- Introduces RISC-V/PIE configuration and dispatch controls.
- Unrolls several generic processing loops.
| File | Description |
|---|---|
src/platform/Kconfig |
Adds ESP32-P4 PIE option. |
src/math/Kconfig.simd |
Adds RISC-V filter selection. |
src/math/Kconfig |
Adds RISC-V filter option. |
src/math/iir_df2t_riscv.c |
Implements RISC-V DF2T IIR. |
src/math/iir_df1_riscv.c |
Implements RISC-V DF1 IIR. |
src/math/fir_generic.c |
Unrolls FIR processing. |
src/math/CMakeLists.txt |
Includes RISC-V IIR sources. |
src/include/sof/math/iir_df2t.h |
Selects RISC-V DF2T helpers. |
src/include/sof/math/iir_df2t_riscv.h |
Adds DF2T format wrappers. |
src/include/sof/math/iir_df1.h |
Selects RISC-V DF1 helpers. |
src/include/sof/math/iir_df1_riscv.h |
Adds DF1 format wrappers. |
src/include/sof/math/fir_generic.h |
Enables generic FIR for RISC-V. |
src/include/sof/math/esp32p4_pie.h |
Defines PIE instruction wrappers. |
src/include/sof/common.h |
Adds RISC-V SIMD macros. |
src/audio/volume/volume_riscv.c |
Adds optimized volume processing. |
src/audio/volume/volume_riscv_with_peakvol.c |
Adds volume and peak metering. |
src/audio/volume/Kconfig.simd |
Adds RISC-V volume selection. |
src/audio/volume/CMakeLists.txt |
Selects RISC-V volume sources. |
src/audio/up_down_mixer/up_down_mixer_hifi3.c |
Adds generic mixer fallbacks. |
src/audio/pcm_converter/pcm_converter_generic.c |
Unrolls PCM conversions. |
src/audio/level_multiplier/level_multiplier-generic.c |
Unrolls level multiplication. |
src/audio/eq_iir/Kconfig.simd |
Adds RISC-V EQ option. |
src/audio/eq_iir/Kconfig |
Sources EQ SIMD configuration. |
src/audio/eq_iir/eq_iir_riscv.c |
Adds block-based RISC-V EQ. |
src/audio/eq_iir/CMakeLists.txt |
Selects RISC-V EQ source. |
src/audio/eq_fir/eq_fir.h |
Enables generic FIR for RISC-V. |
src/audio/eq_fir/eq_fir_generic.c |
Enables generic EQ FIR path. |
src/audio/drc/Kconfig.simd |
Adds RISC-V DRC option. |
src/audio/drc/drc_riscv.c |
Adds optimized DRC processing. |
src/audio/drc/drc_math.h |
Adds RISC-V fixed-point helpers. |
src/audio/drc/drc_math_riscv.c |
Adds optimized DRC math. |
src/audio/drc/drc_generic.c |
Exposes shared RISC-V DRC logic. |
src/audio/drc/CMakeLists.txt |
Includes RISC-V DRC sources. |
src/audio/asrc/asrc_farrow_generic.c |
Unrolls ASRC FIR loops. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Define SOF_CONFIG_RISCV_SIMD and SOF_USE_RISCV_SIMD macros in common.h mirroring SOF_CONFIG_HIFI and SOF_USE_HIFI to allow compile-time selection of architecture-accelerated RISC-V SIMD and DSP processing kernels across audio modules and math libraries. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
1e79e12 to
3d0cb79
Compare
PR Update & Review Comments ResolutionThank you for the detailed review! All 15 findings have been addressed, and the series has been rebased and updated:
All 7 atomic commits are signed off by |
PR 11300: test resultsRun date: 2026-10-13 17:03 UTC Tested commit: 1e79e12989c51a11dc33f3bca1e389c3877ef6fc |
There was a problem hiding this comment.
🟡 Changes recommended
SIMD accuracy, unsafe FIR coefficient loads, DRC selection, and arithmetic correctness issues remain.
7 open findings
Prevent overflow in Q21-to-Q24 compression conversion · New Avoid strict-aliasing violation when loading coefficients · New Avoid unaligned packed coefficient loads · New Preserve per-branch saturation in DF2T processing · New Select the RISC-V SIMD DRC implementation by default · New Preserve scalar rounding in vector gain conversion · New Share configuration and setup code with generic implementation · New
15 resolved since last review
Restrict ESP32-P4-specific SIMD dependency to ESP32-P4 targets Handle all supported input channel geometries Produce high-aligned S32 output in 16-bit fallback paths Add RISC-V defaults to the active Kconfig choice Clamp IPC3 result before narrowing to int32 Prevent overflow in IPC3 gain multiplication Include math.h for fabsf declaration Clamp widened result before narrowing to S24 Restrict PIE conversion to Q8.16 sub-unity gains Widen IPC3 gain multiplication before saturation Derive 5.1 output order from the configured channel map Prevent int32 overflow during rounded S24 conversion Prevent Q1.31 rounding overflow before S16 conversion Use 64-bit accumulation for parallel biquad branches Fix missing default float API and state integration
🧠 Review effort: Balanced
| tmp = compression_diff_db << 3; | ||
| if (tmp > state->max_attack_compression_diff_db) | ||
| state->max_attack_compression_diff_db = tmp; |
There was a problem hiding this comment.
Fixed in commit 416843f. Replaced signed 32-bit shift with sat_int32(Q_SHIFT_LEFT((int64_t)compression_diff_db, 21, 24)) before updating max_attack_compression_diff_db, preserving generic wide saturation and avoiding 32-bit overflow for large compression differences.
| uint32_t c32 = *(const uint32_t *)coef; | ||
| coef += 2; | ||
| y += (int64_t)(int16_t)c32 * data[0]; | ||
| y += (int64_t)(int16_t)(c32 >> 16) * data[-1]; |
There was a problem hiding this comment.
Fixed in commit 889963e. Replaced *(const uint32_t *)coef dereferences with declared int16_t loads (c0 = coef[0]; c1 = coef[1]; coef += 2;) across both segments of fir_32x16 and fir_32x16_2x, eliminating strict-aliasing violations.
| uint32_t c32 = *(const uint32_t *)coef; | ||
| coef += 2; | ||
| y += (int64_t)(int16_t)c32 * data[0]; | ||
| y += (int64_t)(int16_t)(c32 >> 16) * data[-1]; |
There was a problem hiding this comment.
Fixed in commit 889963e. Loading individual 16-bit coefficients avoids 2-byte unaligned uint32_t loads when the initial circular segment length n1 is odd.
| c += SOF_EQ_IIR_NBIQUAD; | ||
| d += IIR_DF2T_NUM_DELAYS; | ||
| } | ||
| out += in; |
There was a problem hiding this comment.
Fixed in commit 889963e. Changed out accumulator to int32_t and apply per-branch saturation out = sat_clamp64((int64_t)out + in); inside the parallel biquad branch loop, matching the generic DF2T saturation contract.
| config DRC_RISCV_SIMD | ||
| prompt "choose RISC-V SIMD optimized DRC module" | ||
| bool |
There was a problem hiding this comment.
Fixed in commit 416843f. Added default DRC_HIFI_MAX if XTENSA, default DRC_RISCV_SIMD if RISCV, and default DRC_HIFI_NONE fallback to the DRC choice, and added depends on RISCV to DRC_RISCV_SIMD, matching the FILTER and VOLUME choices.
| esp_pie_set_sar(15); | ||
| int16_t vol15_l = (int16_t)MIN(32767, (vol_l + 1) >> 1); | ||
| int16_t vol15_r = (int16_t)MIN(32767, (vol_r + 1) >> 1); | ||
| int16_t vol_stereo[2] = { vol15_l, vol15_r }; | ||
| register const void *bc_a2 asm("a2") = vol_stereo; | ||
| ESP_PIE_VLDBC_32_IP_Q2_A2(); |
There was a problem hiding this comment.
Fixed in commit d7c36d2. Dropped the truncated PIE Q15 approximation from vol_s16_to_s16. Both stereo and mono paths now execute the 4-way unrolled scalar loop using vol_mult_s16, guaranteeing full Q8.16 precision, correct rounding, and 100% bit-exact results.
| /* Common config parsing, validation, and setup */ | ||
| static int eq_iir_blob_words_max(struct comp_dev *dev, | ||
| const struct sof_eq_iir_config *config, | ||
| size_t blob_size, | ||
| uint32_t *coef_words_max) |
There was a problem hiding this comment.
Fixed in commit 33fcf97. Moved common configuration parsing, validation, setup, and delayline lifecycle routines from eq_iir_generic.c into eq_iir.c. Removed duplicated setup code from eq_iir_riscv.c so it now strictly provides the optimized processing entry points (eq_iir_s16_default, eq_iir_s24_default, eq_iir_s32_default).
Implement Direct Form 1 (DF1) and Transposed Direct Form 2 (DF2T) biquad filtering kernels optimized for RISC-V architectures: - 64-bit MAC accumulators with branchless saturation (sat_clamp_q31) using compiler branch prediction (__builtin_expect). - Specialized 4th order (2 biquads in series) unrolled kernel. - Dispatch headers iir_df1_riscv.h and iir_df2t_riscv.h for fast inlining. - Add CONFIG_FILTER_RISCV_SIMD choice option in math Kconfig. - 2-way unrolled loops and 32-bit packed coefficient loads in fir_generic.c. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Add src/include/sof/math/esp32p4_pie.h defining portable 128-bit vector SIMD instruction wrappers (PIE / Xespv2p2) using .word machine directives. This ensures 100% build compatibility with standard upstream Zephyr SDK GCC toolchains without requiring custom toolchain patches. Add CONFIG_ESP32P4_PIE_SIMD Kconfig option in platform Kconfig. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Accelerate volume scaling on RISC-V architectures:
- Add CONFIG_VOLUME_RISCV_SIMD choice option in Kconfig.simd.
- Implement volume_riscv.c and volume_riscv_with_peakvol.c:
* Contiguous interleaved stereo streaming (L0, R0, L1, R1),
eliminating strided per-channel loops.
* Branchless saturation (sat_clamp_s16, sat_clamp_s24, sat_clamp_q31)
across S16, S24, and S32 formats.
* Optimized peak volume tracking in volume_riscv_with_peakvol.c.
* Integrated 128-bit vector loops using ESP32-P4 PIE SIMD when
CONFIG_ESP32P4_PIE_SIMD is enabled, providing 8.46x speedup on silicon.
Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
… saturation
Implement block-accelerated IIR equalizer for RISC-V architectures:
- Add CONFIG_EQ_IIR_RISCV_SIMD Kconfig option.
- Implement eq_iir_riscv.c:
* Block vector processing kernel keeping filter delay states
(y_n2, y_n1, x_n2, x_n1) and biquad coefficients in CPU registers
across each block (EQ_IIR_BLOCK_SIZE = 64 samples).
* Eliminates ~98% of RAM load/store operations per block.
* Inlines biquad loop to eliminate 96 external function call dispatches/ms.
* Fast branchless saturation for S16, S24, and S32 formats.
* Yields 22.2% reduction in computational cycles on silicon.
Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement RISC-V optimizations for Dynamic Range Compressor: - Add CONFIG_DRC_RISCV_SIMD choice option in DRC Kconfig.simd. - Implement drc_math_riscv.c with Horner's polynomial evaluations for: log10_fixed, drc_lin2db_fixed, drc_log_fixed, drc_asin_fixed, drc_inv_fixed. - Implement fast knee_curveK, volume_gain, and envelope tracking. - Implement drc_riscv.c with vectorized 4-sample unrolled output compression. - Update drc_generic.c guards for SOF_USE_RISCV_SIMD(DRC). - Reduces DRC computational load by 57.2% (18.88 vs 44.22 MCPS) on silicon. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
…sue pipelines Optimize generic processing paths for dual-issue RISC-V execution pipelines: - asrc: 4-way loop unrolling in asrc_fir_filter16() and asrc_fir_filter32(). - level_multiplier: add SOF_USE_RISCV_SIMD(VOLUME) guards and 4-way loop unrolling for s16, s24, and s32 integer gain scaling. - pcm_converter: 4x and 8x loop unrolling for integer conversions (s16_to_s24, s24_to_s16, s16_to_s32, s32_to_s16, s24_to_s32, s32_to_s24). - eq_fir: update fallback guards to include SOF_USE_RISCV_SIMD(FILTER). Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
3d0cb79 to
9324602
Compare
|
Addressed review comments from the latest review pass:
|



Description
This series introduces architecture-accelerated SIMD, vector, and DSP math optimizations for RISC-V cores (
CONFIG_RISCV).Previously, these optimizations were developed within board-bringup branches and PRs (such as #11194 and #11200) alongside platform drivers, static topologies, and USB classes. To facilitate focused review and upstream merging, this series isolates the generic audio processing and math kernels into 8 atomic, module-by-module commits cleanly rebased onto upstream
main.All board, platform, and application-specific code has been eliminated. The optimizations target standard RISC-V DSP execution, with vendor extensions (such as ESP32-P4 PIE 128-bit vector SIMD) conditionally guarded.
Module-by-Module Summary
include: common: introduce RISC-V SIMD configuration macrosSOF_CONFIG_RISCV_SIMD(component)andSOF_USE_RISCV_SIMD(component)macros mirroringSOF_CONFIG_HIFI/SOF_USE_HIFIfor compile-time optimization selection.math: iir: add RISC-V SIMD cascaded DF1 and DF2T biquad filteringiir_df1_riscv.c) and Transposed Direct Form 2 (iir_df2t_riscv.c) biquads.sat_clamp_q31) using compiler branch prediction (__builtin_expect).CONFIG_FILTER_RISCV_SIMD.include: math: add ESP32-P4 PIE 128-bit vector SIMD definitionssrc/include/sof/math/esp32p4_pie.hdefining 128-bit vector instructions (PIE / Xespv2p2) using.wordmachine directives.CONFIG_ESP32P4_PIE_SIMD.audio: volume: add RISC-V SIMD and contiguous vector streamingvldbc.32.ip,vmul.s16,vclamp.s16,vst.128.ip) when enabled. AddsCONFIG_VOLUME_RISCV_SIMD.audio: eq_iir: add RISC-V block-accelerated processing and branchless saturationEQ_IIR_BLOCK_SIZE = 64) keeping filter delay states (y_n2,y_n1,x_n2,x_n1) and coefficients in registers across each block, eliminating ~98% of RAM load/store traffic.CONFIG_EQ_IIR_RISCV_SIMD.audio: drc: add RISC-V SIMD and fast polynomial math optimizationslog10_fixed,drc_lin2db_fixed,drc_log_fixed,drc_asin_fixed,drc_inv_fixed).knee_curveK, volume gain, and envelope tracking.CONFIG_DRC_RISCV_SIMD.audio: up_down_mixer: add ANSI C and RISC-V upmix and downmix routinessof_panic(0)stubs with working ANSI C & RISC-V upmix, downmix, and shift-copy routines across all surround channel geometries (1, 2.0, 3.0, 4.0, 5.0, 5.1, 7.1) for both 16-bit and 32-bit audio.audio: modules: optimize loop unrolling and guards for RISC-V dual-issue pipelinesasrc_fir_filter16,asrc_fir_filter32).SOF_USE_RISCV_SIMD(VOLUME)guards in Level Multiplier.s16_to_s24,s24_to_s16,s16_to_s32,s32_to_s16,s24_to_s32,s32_to_s24).SOF_USE_RISCV_SIMD(FILTER)in EQ FIR.Measured Hardware Performance (Physical Silicon)
Benchmarks measured on 400 MHz physical RISC-V silicon:
Verification
-marchor toolchain patches required).