【问题标题】:Why does the loop direction of my filter change my result?为什么我的过滤器的循环方向会改变我的结果?
【发布时间】:2020-05-20 08:04:29
【问题描述】:

我设计了一个简单的双通道滤波器来去除给定频率的一些噪声。

#include "../include/Filter.h"

void Filter(int DataIn, int* DataOut, bool Enable)
{
    static coef_t Coefficients[] = {
            0.0076925293, -0.039817952, 0.018740745, 0.013075141, -0.052312399,
            0.052374545, 0.017044802, -0.14227364, 0.26541378, 0.68194015, 0.26541378,
            -0.14227364, 0.017044802, 0.052374545, -0.052312399, 0.013075141, 0.018740745,
            -0.039817952, 0.0076925293
    };

    static data_t ShiftRegRight[LENGTH];
    static data_t ShiftRegLeft[LENGTH];

    acc_t AccRight = 0x00;
    acc_t AccLeft = 0x00;

    if(Enable == true)
    {
        Shift_Accum_Loop: for(int i = (LENGTH - 1); i >= 0; i--)
        {
            if(i == 0)
            {
                ShiftRegRight[0] = DataIn & 0x0000FFFF;
                ShiftRegLeft[0] = (DataIn & 0xFFFF0000) >> 0x10;
            }
            else
            {
                ShiftRegRight[i] = ShiftRegRight[i - 1];
                ShiftRegLeft[i] = ShiftRegLeft[i - 1];
            }

            AccRight += ShiftRegRight[i] * Coefficients[i];
            AccLeft += ShiftRegLeft[i] * Coefficients[i];
        }

        *DataOut = ((AccLeft.range() >> 0x20) << 0x10) | (AccRight.range() >> 0x20);
    }
    else
    {
        *DataOut = DataIn;
    }
}

此过滤器在给定的测试信号上产生以下输出:

0, 0, 0
1, 28377, 218
2, 0, 64405
3, 0, 531
4, 0, 370
5, 37159, 63833
6, 0, 2616
7, 37159, 65269
8, 0, 62257
9, 0, 8484
10, 0, 17494
11, 28377, 8750
12, 0, 62919
13, 28377, 58754
14, 0, 50948
15, 0, 48035
16, 0, 52449
17, 37159, 56833
18, 0, 0
19, 37159, 8484
20, 0, 14216
21, 0, 16968
22, 0, 14216
...

使用测试台生成测试信号:

#include <math.h>
#include <stdio.h>

#include "../include/Filter.h"

#define SAMPLES                 48000
#define FREQ_RIGHT_1            8000
#define FREQ_RIGHT_2            10000
#define FREQ_LEFT_1             50

FILE* File;

int main(void)
{
    int Output;
    int StreamData;
    uint16_t RightChannel = 0x00;
    uint16_t LeftChannel = 0x00;

    File = fopen("Result.log", "w");
    for(int i = 0x00; i < SAMPLES; i++)
    {
        // Generate the input data
        RightChannel = 32767 * sin(2 * M_PI * i / (SAMPLES / FREQ_RIGHT_1)) * sin(2 * M_PI * i / (SAMPLES / FREQ_RIGHT_2));
        StreamData = (LeftChannel << 0x10) | RightChannel;

        // Execute the function with latest input
        Filter(StreamData, &Output, true);

        // Write the simulation results
        fprintf(File, "%i, %d, %d\n", i, StreamData, Output);
    }

    fclose(File);
}

那么,当我将Filter 中的for 循环从向下计数循环更改为向上计数循环时,为什么会得到不同的输出?

if(Enable == true)
{
    Shift_Accum_Loop: for(int i = 0; i < (LENGTH - 1); i++)
    {
        if(i == 0)
        {
            ...

0, 0, 0
1, 28377, 27073
2, 0, 0
3, 0, 0
4, 0, 0
5, 37159, 38462
6, 0, 0
7, 37159, 38462
8, 0, 0
9, 0, 0
10, 0, 0
11, 28377, 27073

这有什么区别?在这两种情况下,循环确实从0 计数到(LENGTH - 1),并且过滤器是对称的。为什么计数方向会影响结果?

【问题讨论】:

  • 与您的问题完全无关,但Shift_Accum_Loop 标签的用途是什么?您打算使用goto 吗?然后不要。如果您将它作为关于循环的“评论”,那么请写一个适当的评论,解释循环的作用以及循环这样做的原因。
  • 至于您的问题,您是否尝试过在调试器中逐句逐句遍历循环的不同实现?想想像ShiftRegRight[i] = ShiftRegRight[i - 1]; 这样的赋值,以及ShiftRegRight 数组的初始值可能是什么。
  • @Someprogrammerdude 该标签仅适用于 HLS 指令,而不适用于某种 goto 或类似的东西。

标签: c++ vivado vivado-hls


【解决方案1】:
if(i == 0)
        {
            ShiftRegRight[0] = DataIn & 0x0000FFFF;
            ShiftRegLeft[0] = (DataIn & 0xFFFF0000) >> 0x10;
        }
        else
        {
            ShiftRegRight[i] = ShiftRegRight[i - 1];
            ShiftRegLeft[i] = ShiftRegLeft[i - 1];
        }

当您倒计时时,i==0 最后评估为真。

当您计数时,i==0 首先评估为真。

【讨论】:

    猜你喜欢
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 2021-10-31
    相关资源
    最近更新 更多