I have reduced a programme to the minimum and get the error
xrun: Program received signal ET_LOAD_STORE, Memory access exception.
0x0004035c in lib_dsp_filters_fir ()
The programme is
#include <lib_dsp.h>
void TestFIR()
{
int32_t sample = Q28(0);
int32_t filter_coeff[5] = { Q28(0.5),Q28(-0.5),Q28(0.0),Q28(-0.5),Q28(0.5) };
int32_t filter_state[4] = { 0, 0, 0, 0 };
int32_t result = lib_dsp_filters_fir( sample, filter_coeff, filter_state, 5, 28 );
}
int main()
{
TestFIR();
return 0;
}
This is running on a XUF216-512-FB236 part.
Please help me to resolve this,
It appears to be cured by forcing the two arrays to be on 64bit boundaries. If this is the case is there a Pragma or similar to enforce this?
Program received signal ET_LOAD_STORE, Memory access excepti
-
- Member++
- Posts: 24
- Joined: Sat Nov 14, 2015 3:53 pm
-
Verified
- Experienced Member
- Posts: 117
- Joined: Fri Dec 11, 2009 10:22 am
If you place the array into global space then it will be 64 bit aligned. There is currently no pragma for doing this although there may be one day.
-
- XCore Addict
- Posts: 230
- Joined: Wed Mar 10, 2010 12:46 pm
You could always make it an array of 64-bit items which can then be pointed to. This will then be 64-bit aligned.
int64_t filter_coeff_64[3];
int32_t *filter_coeff = (int32_t*)&filter_coeff_64[0];
int64_t filter_coeff_64[3];
int32_t *filter_coeff = (int32_t*)&filter_coeff_64[0];
-
- Respected Member
- Posts: 367
- Joined: Wed May 31, 2017 6:55 pm
I just had the same problem. I have two tasks running biquad filters on four I2S data streams. I'd like to keep the filter state private to each task, but then it fails with this exception. It looks like I might have to make the filter state arrays global and pass a reference to each task, but I'll give Peter's workaround a go first.
+1 for that pragma.
+1 for that pragma.
-
- New User
- Posts: 3
- Joined: Fri Dec 07, 2018 7:09 am
peter wrote:You could always make it an array of 64-bit items which can then be pointed to. This will then be 64-bit aligned.
The xmos cpu is 32bit. What is the point of making an array of 64-bit?
int64_t filter_coeff_64[3];
int32_t *filter_coeff = (int32_t*)&filter_coeff_64[0];
-
- Member
- Posts: 13
- Joined: Thu Jan 24, 2019 7:35 pm
I'm getting basically the same problem, making the arrays passed into the filter function global only works when I call the same arrays. I getting the error again when I call 'dsp_filters_biquad()' twice but with different global arrays each time:
samples[0] = dsp_filters_biquad(l_sample[0], b_c1, b_s1, 28);
samples[1] = dsp_filters_biquad(l_sample[1], b_c2, b_s2, 28);
Which gives me the error:
xrun: Program received signal ET_LOAD_STORE, Memory access exception.
[Switching to tile[0] core[1] (dual issue)]
dsp_filters_biquad (input_sample=0, filter_coeffs=0x7f9f8, state_data=0x7f9d4, q_format=28) at C:/Users/stnsc/workspace/lib_dsp/src\dsp_filters.c:1089
1089 asm("ldd %0,%1,%2[0]":"=r"(s2),"=r"(s1):"r"(state_data));
Current language: auto; currently minimal
The curious thing is is that I don't get this error if I use the same input arrays in both calls:
This works:
samples[0] = dsp_filters_biquad(l_sample[0], b_c1, b_s1, 28);
samples[1] = dsp_filters_biquad(l_sample[1], b_c1, b_s1, 28);
..and this works:
samples[0] = dsp_filters_biquad(l_sample[0], b_c2, b_s2, 28);
samples[1] = dsp_filters_biquad(l_sample[1], b_c2, b_s2, 28);
Why is this function behaving differently when I use a different set of array inputs?
samples[0] = dsp_filters_biquad(l_sample[0], b_c1, b_s1, 28);
samples[1] = dsp_filters_biquad(l_sample[1], b_c2, b_s2, 28);
Which gives me the error:
xrun: Program received signal ET_LOAD_STORE, Memory access exception.
[Switching to tile[0] core[1] (dual issue)]
dsp_filters_biquad (input_sample=0, filter_coeffs=0x7f9f8, state_data=0x7f9d4, q_format=28) at C:/Users/stnsc/workspace/lib_dsp/src\dsp_filters.c:1089
1089 asm("ldd %0,%1,%2[0]":"=r"(s2),"=r"(s1):"r"(state_data));
Current language: auto; currently minimal
The curious thing is is that I don't get this error if I use the same input arrays in both calls:
This works:
samples[0] = dsp_filters_biquad(l_sample[0], b_c1, b_s1, 28);
samples[1] = dsp_filters_biquad(l_sample[1], b_c1, b_s1, 28);
..and this works:
samples[0] = dsp_filters_biquad(l_sample[0], b_c2, b_s2, 28);
samples[1] = dsp_filters_biquad(l_sample[1], b_c2, b_s2, 28);
Why is this function behaving differently when I use a different set of array inputs?
-
- Experienced Member
- Posts: 83
- Joined: Sun Apr 08, 2018 11:19 pm
I'm getting the same issue, I tried Pete's workaround but I still get problems, some of which are due to trying to create an 80 Hz high-pass filter at sample rates from 44.1 kHz to 96 kHz, so I looked for an example of a double precision filter. I found this on Github:
https://github.com/t123yh/xmos_dsp_doub ... ion_biquad
Double Precision Biquad Filter for XMOS XS2 DSP
Biquad filters suffer from quantization noise, especially the fixed-point ones. This library reimplements XMOS the biquad filter library with double precision y states, eliminates the quantization noise.
Usage
Identical to the standard single-precision dsp_filters_biquad function, except that you need a 6-word state_data instead of 4-word in official version.
Use cases
This function is slightly higher in computation cost (67 instructions in -O2, vs 46 instructions of the standard version). You may use the double-precision version where a low frequency is required (for example, bass enhance EQ), and use the standard version in other places where the frequency is above 200Hz.
I've indicated the line that causes the runtime exception:
This is the ET_LOAD_STORE error it produces when inserted in my application:
xrun: Program received signal ET_LOAD_STORE, Memory access exception.
[Switching to tile[0] core[3]]
dsp_filters_biquad_double_precision (input_sample=29349, filter_coeffs=<value optimized out>, state_data=<value optimized out>) at ../src/200123 Integration.xc:68
68 asm("ldd %0,%1,%2[0]":"=r"(c2),"=r"(c1):"r"(filter_coeffs)); // c2 = b1, c1 = b0
Any ideas or suggestions welcome!
I'm going to share with my local XMOS support as I think there is something very broken with the way that all the filter functions have been implemented. Other than that I guess I'll be writing my own filter code.
Kind regards,
Al
https://github.com/t123yh/xmos_dsp_doub ... ion_biquad
Double Precision Biquad Filter for XMOS XS2 DSP
Biquad filters suffer from quantization noise, especially the fixed-point ones. This library reimplements XMOS the biquad filter library with double precision y states, eliminates the quantization noise.
Usage
Identical to the standard single-precision dsp_filters_biquad function, except that you need a 6-word state_data instead of 4-word in official version.
Use cases
This function is slightly higher in computation cost (67 instructions in -O2, vs 46 instructions of the standard version). You may use the double-precision version where a low frequency is required (for example, bass enhance EQ), and use the standard version in other places where the frequency is above 200Hz.
I've indicated the line that causes the runtime exception:
This is the ET_LOAD_STORE error it produces when inserted in my application:
xrun: Program received signal ET_LOAD_STORE, Memory access exception.
[Switching to tile[0] core[3]]
dsp_filters_biquad_double_precision (input_sample=29349, filter_coeffs=<value optimized out>, state_data=<value optimized out>) at ../src/200123 Integration.xc:68
68 asm("ldd %0,%1,%2[0]":"=r"(c2),"=r"(c1):"r"(filter_coeffs)); // c2 = b1, c1 = b0
Any ideas or suggestions welcome!
I'm going to share with my local XMOS support as I think there is something very broken with the way that all the filter functions have been implemented. Other than that I guess I'll be writing my own filter code.
Kind regards,
Al
You do not have the required permissions to view the files attached to this post.
-
- XCore Expert
- Posts: 580
- Joined: Thu Nov 26, 2015 11:47 pm
The error isn't on the line you indicated. It's 5 lines up. Are you sure that filter_coeffs is 64 bit aligned per above?
-
- Junior Member
- Posts: 5
- Joined: Thu Nov 30, 2023 7:49 pm
I ran into this problem in a .C file (not .XC), with dsp_complex_t arrays allocated in global memory. I couldn't find any good reference/documentation/sample-code for the solution I came up with (just some similar-to-below syntax that would not compile) ... I actually had to hack around to figure out "aligned(8)", but this example seems to work:
dsp_complex_t __attribute__((aligned(8))) fft_io[256];
I also saw a bug report on Github that might have saved me, and perhaps others, a lot of frustration had it actually been implemented: https://github.com/xmos/lib_dsp/issues/124
This was a weird bug that showed up depending on whether I tested a certain unrelated (but global) int variable to call an unrelated function. If I tested the variable, an unrelated call to dsp_complex_fir() would throw the ET_LOAD_STORE! If I commented that unrelated test out, no ET_LOAD_STORE! I'll guess the compiler optimized the variable out, and changed the alignment of a dsp_complex_t array that followed it.
dsp_complex_t __attribute__((aligned(8))) fft_io[256];
I also saw a bug report on Github that might have saved me, and perhaps others, a lot of frustration had it actually been implemented: https://github.com/xmos/lib_dsp/issues/124
This was a weird bug that showed up depending on whether I tested a certain unrelated (but global) int variable to call an unrelated function. If I tested the variable, an unrelated call to dsp_complex_fir() would throw the ET_LOAD_STORE! If I commented that unrelated test out, no ET_LOAD_STORE! I'll guess the compiler optimized the variable out, and changed the alignment of a dsp_complex_t array that followed it.
-
Verified
- XCore Legend
- Posts: 1163
- Joined: Thu Dec 10, 2009 9:20 pm
- Location: Bristol, UK
I've reopened the issuebmc3 wrote: ↑Tue Dec 19, 2023 11:41 pm I ran into this problem in a .C file (not .XC), with dsp_complex_t arrays allocated in global memory. I couldn't find any good reference/documentation/sample-code for the solution I came up with (just some similar-to-below syntax that would not compile) ... I actually had to hack around to figure out "aligned(8)", but this example seems to work:
dsp_complex_t __attribute__((aligned(8))) fft_io[256];
I also saw a bug report on Github that might have saved me, and perhaps others, a lot of frustration had it actually been implemented: https://github.com/xmos/lib_dsp/issues/124
This was a weird bug that showed up depending on whether I tested a certain unrelated (but global) int variable to call an unrelated function. If I tested the variable, an unrelated call to dsp_complex_fir() would throw the ET_LOAD_STORE! If I commented that unrelated test out, no ET_LOAD_STORE! I'll guess the compiler optimized the variable out, and changed the alignment of a dsp_complex_t array that followed it.
Technical Director @ XMOS. Opinions expressed are my own