Jump to content

    

Паразитные гармоники в спектре XFFT

Доброго времени суток, уважаемые форумчане. Балуюсь с ядром ПФ в Vivado.
Ядро сконфигурировано следующим образом:
- размер - 8192 точки.
- Тактовая - 100 МГц.
- Сэмплинг - 100 Msps.
- Без масштабирования (Unscaled).
- convergent rounding.
- натуральный порядок вывода.
В качестве тестового сигнала использую сумму двух комплексных экспонент, однак на выходе модуля получаю паразитные гармоники (см. рис.). Причем, мнимая часть более ли менее похожа на правда, а шум появляется именно в реальной части. Чем это может быть вызвано и как с таким бороться? На сколько правильно вообще у меня сконфигурировано ядро?
Заранее благодарен за ответы.
Код модуля:
 

module tb_xfft();

    reg CLK = 0; always #5 CLK = ~CLK;
    wire [31:0] signal1, signal2, signal;
    wire signal1_valid, signal2_valid, signal_valid;
    assign signal_valid = signal1_valid & signal2_valid;
    
    
    dds_out16 inst_dds_out16(
        .aclk(CLK),
        .m_axis_data_tdata(signal1),
        .m_axis_data_tvalid(signal1_valid)
    );
    
    dds_out16_3M inst_dds_out16_3M(
        .aclk(CLK),
        .m_axis_data_tdata(signal2),
        .m_axis_data_tvalid(signal2_valid)
    );
    
    wire signed [15:0] sin1, cos1, sin2, cos2, sin, cos;
    wire signed [16:0] ssin, scos;
    assign sin1 = signal1[31:16];
    assign cos1 = signal1[15:0];
    assign sin2 = signal2[31:16];
    assign cos2 = signal2[15:0];
    assign ssin = sin1 + sin2;
    assign scos = cos1 + cos2;
    assign sin = ssin[16:1];
    assign cos = scos[16:1];
    assign signal = {sin, cos};
    
    wire fft_valid;
    wire [31:0] fft;
    wire new_fft;
    
    wire config_valid;
    reg [7:0] config_data = {7'b0, 1'b1}; 
        
    xfft inst_xfft(
        .aclk(CLK),//aclk : IN STD_LOGIC;
        
        .s_axis_config_tdata(config_data),//s_axis_config_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
        .s_axis_config_tvalid(config_valid),//s_axis_config_tvalid : IN STD_LOGIC;
        .s_axis_config_tready(config_valid),//s_axis_config_tready : OUT STD_LOGIC;
        
        .s_axis_data_tdata(signal),//s_axis_data_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
        .s_axis_data_tvalid(signal_valid),//s_axis_data_tvalid : IN STD_LOGIC;
        //.s_axis_data_tready(),//s_axis_data_tready : OUT STD_LOGIC;
        
        //.s_axis_data_tlast(),//s_axis_data_tlast : IN STD_LOGIC;
        .m_axis_data_tdata(fft),//m_axis_data_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
        .m_axis_data_tvalid(fft_valid),//m_axis_data_tvalid : OUT STD_LOGIC;
        .m_axis_data_tready(1),//m_axis_data_tready : IN STD_LOGIC;
        //m_axis_data_tlast : OUT STD_LOGIC;
        .event_frame_started(new_fft)
    );
    
    wire [15:0] fft_re, fft_im;
    assign fft_re = fft[15:0];
    assign fft_im = fft[31:16];
    wire [31:0] Re, Im;
    
    mult_16x16 inst_mult_re(
        .CLK(CLK),
        .A(fft_re),
        .B(fft_re),
        .P(Re)
    );
    
    mult_16x16 inst_mult_im(
        .CLK(CLK),
        .A(fft_im),
        .B(fft_im),
        .P(Im)
    );
    
    reg [32:0] Abs = 0;
    always @(posedge CLK) begin
        if (fft_valid) begin Abs <= Re + Im; end
        else begin Abs <= 0; end
    end

endmodule

 

fft1.PNG

fft2.PNG

Share this post


Link to post
Share on other sites

Для начала возьмите только один сигнал с dds. Подайте его на бпф, сделайте бпф 16 точечным,чтобы легче было разобраться. После нахождения амплитуды комплексного сигнала у вас будут повторяющиеся комбинации чисел и нужный вам Бин будет повторяться каждые 16 отсчётов, остальные бины (отсчёты) должны быть близки к нулю.. Когда получите стабильные данные и нужный вам Бин, тогда переходите к сумме сигналов. Также учтите, что с выхода dds синусоида может появиться не мгновенно и какое-то количество данных уйдет на переходной процесс

Share this post


Link to post
Share on other sites
10 hours ago, Skryppy said:

Для начала возьмите только один сигнал с dds. Подайте его на бпф, сделайте бпф 16 точечным,чтобы легче было разобраться. После нахождения амплитуды комплексного сигнала у вас будут повторяющиеся комбинации чисел и нужный вам Бин будет повторяться каждые 16 отсчётов, остальные бины (отсчёты) должны быть близки к нулю.. Когда получите стабильные данные и нужный вам Бин, тогда переходите к сумме сигналов. Также учтите, что с выхода dds синусоида может появиться не мгновенно и какое-то количество данных уйдет на переходной процесс

Попробовал с разным размером выборки для чистого тона. Ощущение, буто что-то напутано с реальной частью. Посмотреть re и im сразу для разного размера ума не хватило, сейчас повторю эксперимент, но новая Vivado жутко тормозит.

fft_16.PNG

fft_64.PNG

fft_256.PNG

fft_1024.PNG

Share this post


Link to post
Share on other sites

Смотреть отдельно re и im вам ничего не даст, смотреть надо вычисленную амплитуду. А вы точно уверены, что dds выдает сигнал, может дело в нём?

Share this post


Link to post
Share on other sites

@Skryppy, да, в первом посте видно сигнал из двух синусоид. И в случае чистого тона тоже проверял сигнал с выхода генератора.

Share this post


Link to post
Share on other sites

Всему виной стала собственная невнимательность. Неверно считывал данный с выходной шины xfft. В результате - реальная часть была просто младшими шумящими разрядами.
@Skryppy, спасибо за помощь.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this