Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unexpected output #5

Open
akukulanski opened this issue Jun 26, 2020 · 3 comments
Open

unexpected output #5

akukulanski opened this issue Jun 26, 2020 · 3 comments

Comments

@akukulanski
Copy link

Hello!

I run a testbench with random input data and found out that about half of the times the output doesn't match the expected result (dismissing some rounding error). In some runs the output data matches the expected result for the DFT while in some others the output data alternates samples in the form of "right-wrong-right-wrong-...".

If I calculate the difference between the output vs expected in the wrong samples, the abs() is always about 16384 (max value for 14 bits, or 15 if signed), which makes me think of an overflow somewhere.. but not sure really.

Here goes an horrible dump of the first values in a test example, where the complex numbers in the left are the output samples, and the ones in the right are the expected values:

d, r = ((-21120+44291j), (-21120+44291j)) (err = 0.0)
d, r = ((-77852-20660j), (-77855-37045j)) (err = 16385.00027464144)
d, r = ((-30079+14j), (-30078+14j)) (err = 1.0)
d, r = ((-33996-5932j), (-43099+7690j)) (err = 16383.634914145274)
d, r = ((29684-18098j), (29684-18097j)) (err = 1.0)
d, r = ((-21408-9626j), (-6272-15895j)) (err = 16382.883049085103)
d, r = ((31267+13250j), (31268+13250j)) (err = 1.0)
d, r = ((283+31702j), (-15786+28506j)) (err = 16383.747343022596)
d, r = ((10194-12038j), (10194-12039j)) (err = 1.0)
d, r = ((-6952-10386j), (4633+1200j)) (err = 16384.371242131936)
d, r = ((-27051+23808j), (-27052+23807j)) (err = 1.4142135623730951)
d, r = ((-5240-9459j), (-8436-25528j)) (err = 16383.747343022596)
d, r = ((-6422+174j), (-6422+174j)) (err = 0.0)
d, r = ((-656+28250j), (-6926+43386j)) (err = 16383.265730616713)
d, r = ((18130+40819j), (18130+40819j)) (err = 0.0)
d, r = ((-4588-12407j), (9036-21510j)) (err = 16385.297830677355)

Something that could also help is that if I write real inputs (with the lowest 16 bits corresponding to the imaginary component = 0) the algorithm works flawlessly.

I'm leaving the testcase here and also an example with the input/output data and waveforms: testcase.tar.gz

Let me know if I can help with more info or by checking something else!
Thanks!

@ZipCPU
Copy link
Owner

ZipCPU commented Jun 27, 2020

If you take the IFFT of the ouput, and compare it to the input, you can see there were two overflows in the first stage at positions 26 and 90.

Digging a bit further, in timestep 1660, in stage_128.FWBFLY.bfly.do_rnd_right_i.genblk8, you have the input 0x7baafdf4e0. (This is one of two problematic timesteps, but one should be sufficient for discussion.) This gets truncated to 17'h0eabf or rounded to 17'h0eac0, both of which lose the sign bit.

Try adding another bit to your incoming signal, or dropping your amplitude by 2x to avoid overflow.

Dan

@akukulanski
Copy link
Author

Thanks for answering :)

Nice approach, I couldn't find where the overflow was happening. Reducing the amplitude is a good workaround, but I'm not sure if that's enough to be certain that there couldn't be any overflows in some stage. Is that it?

Have you considered that the cpp generator implements the addition of this bit (or the division by 2) in the input so full-range inputs would not cause overflows, without having to take care of that from outside the core? (assuming this bit addition is enough)

Thanks,

K.

@ZipCPU
Copy link
Owner

ZipCPU commented Jul 1, 2020

Have you considered that the cpp generator implements the addition of this bit (or the division by 2) in the input so full-range inputs would not cause overflows, without having to take care of that from outside the core?

Yeah, I'm looking into that. That's supposed to be what takes place.

At issue is how many bits to drop in the first stage (or any stage thereafter). My general rule of thumb, backed by a lot of math, has been to drop one bit every other stage--since that's the rate the noise accumulates. It's also been appropriate for most of my uses of the core so far. That said, overflow is a bad thing ... so, it's something I'm (now) looking into (again).

Dan

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

No branches or pull requests

2 participants