关于xilinx的FFTIP的使用和仿真

news2024/12/26 0:42:19

工具:vivado2018.3,modelsim10.6d

场景:在进行数据进行频谱分析的时候,使用FPGA来完成FFT的计算可以加快数据的计算速度。

下面使用仿真完成DDS产生的数据的FFT以及IFFT。原始数据使用DDSIP产生,通过IP产生的波形数据直接输入到FFT进行傅里叶正变换。然后再使用FFT对数据进行IFFT傅里叶逆变换还原波形数据。过程中完成了fftshift(将零频分量搬移到频谱中心),以及使用cordic计算平方根的过程。

FFT端口说明

端口名称

方向

描述

aclk

I

时钟

aresetn

I

复位

s_axis_config_tvalid

I

配置有效

s_axis_config_tready

O

配置准备好

s_axis_config_tdata

I

针对配置通道的TDATA。携带配置信息: CP_LEN、FWD/INV、NFFT和SCALE_SCH。关于FWD/INV为FFTIP的方式,1为FFT,0为IFFT。当选择FFT点数可配置时NFFT为点数。SCALE_SCH为缩放计划,以确保在计算过程中不溢出。对于不同的IO架构有不同的规则。

s_axis_data_tdata

I

输入数据

s_axis_data_tvalid                

I

数据有效

s_axis_data_tready

O

数据准备好

s_axis_data_tlast

I

输入的一帧最后一个数据

m_axis_data_tvalid

O

输出数据有效

m_axis_data_tready

I

输出数据准备好

m_axis_data_tdata

O

输出数据

m_axis_data_tuser

O

输出数据状态参数。包含XK_INDEX, OVFLO, and BLK_EXP.

XK_INDEX输出数据索引

OVFLO溢出标志
BLK_EXP块指数,字段中出现的值表示在转换过程中数据被缩放的比特总数。例如,如果BLK_EXP的值为00101 = 5,这意味着相关的输出数据(XK_RE,XK_IM)被缩放为5位(向右移5位),或者换句话说,被除以32,以充分利用输出数据路径的可用动态范围而不会溢出。

m_axis_data_tlast

O

输出的最后一个数据。

m_axis_status_tvalid

O

状态有效

m_axis_status_tready

I

状态准备好

m_axis_status_tdata

O

状态数据。包含每一帧的状态休息。

event_frame_started

O

事件帧开始

event_tlast_unexpected

O

当核心在不是帧中最后一个的数据样本上看到s_axis_data_tlast高时有效

event_tlast_missing

O

当一帧的最后一个数据样本上的s_axis_data_tlast为低时断言。

event_fft_overflow

O

当正在从数据输出通道卸载的数据样本中出现溢出时断言。仅在溢出是一个有效的选项时才会出现。

event_data_in_channel_halt

O

当核心从数据输入通道请求数据而没有数据可用时断言。

event_data_out_channel_halt

O

当核心从数据输入通道请求数据而没有数据可用时断言。

event_status_in_channel_halt

O

当核心试图将数据写入状态通道而无法这样做时,将被断言。仅在非实时模式下出现。

FFT IP的配置界面

Channels:从1到12中选择通道数。三种Burst I/O架构均可使用多通道操作。对于浮点格式,通道必须为1。

Transform Length: 选择一次处理所需点的大小。

The Pipelined Streaming I/O:运行连续处理。

Radix-4,Radix-2,Radix-2 Lite Burst I/O。几种不同的实现方式,延迟依次增大,资源依次减少。

Run time configurable Transform Length:允许运行的过程中改变点数。勾选此后注意,s_axis_config_tdata的字段的意义。

DataFormat:选择输入和输出数据样本是否为定点格式,或在IEEE-754单精度(32位)浮点格式中。浮点格式不是当核心处于多通道配置时可用。

Scaling Options:

Scaling:用户自定义缩放格式。注意s_axis_config_tdata的字段需要配置每个阶段的缩放信息。

Block Floating-Point:由核心来判断所需的缩放程度,以实现对可用动态范围的最佳利用,并以块指数的形式报告缩放因子。注意m_axis_data_tuser字段的块指数报告。

Output ordering:自然顺序和反转顺序。这里使用自然顺序。

Optional Output Fields:XK_INDEX,输出数据索引。

资源消耗设置界面。

关于matlab仿真,产生1MHZ的正弦波余弦波信号,采样率为100MHZ。共计1024个点。对其进行FFT。

matlab仿真程序

% 生成正弦波
fc = 1e6;               % 频率
fs = 100e6;             % 采样率
t1 = 0:1/fs:1e-3;       % 时间序列,1微秒
t = t1(1:1024);         %RW需要取整数计算出的频率是真实

sin_wave = sin(2 * pi * fc * t);
cos_wave = cos(2 * pi * fc * t);

% 复数
plural_wave = cos_wave+ 1i*sin_wave;

% 加噪声
data =awgn(cos_wave,100) ;
% data =awgn(plural_wave,100) ;

% 绘制原始正弦波数据
figure;
subplot(1,1,1);
plot(t*1e9, imag(plural_wave));
title('原始正弦波');
xlabel('时间 (ns)');
ylabel('幅值');


%%做FT变化,算平均功率谱,并画谱输出
FFT_data = data; N = length(FFT_data); w = blackman(N);Fs =100e6;
% Sf_I_Q_wave=fftshift(fft((FFT_data).*w',N)*2.381);
% w = gausswin(N);%高斯窗函数,窗长度为N
gauss_data = fft((FFT_data).*w',N)*2.396;%%做FFT变换,加窗并还原窗系数
Sf_I_Q_wave=fftshift(gauss_data);
Sf_I_Q_wave_dBm =(abs(Sf_I_Q_wave));
% Sf_I_Q_wave_dBm =20*log10(1/N*abs(Sf_I_Q_wave));
X_freq=Fs.*(-N/2:N/2-1)/N;figure(2);plot(X_freq,Sf_I_Q_wave_dBm);title('plural_wave原始数据普');

对实信号余弦波进行傅里叶变换,频谱图如下。

对复信号进行进行傅里叶变换频谱。

在逻辑中我们使用DDSIP来产生我们需要的波形数据。

DDS IP配置界面

可以看到我需要控制DDS的控制字来生成不同频率的波形数据,输出数据的格式为高16位为正弦,低16位为余弦。

输出频率计算公式。

其中X为频率控制字,Fs采样率,即系统时钟。N为多少位的控制字。要输出1MHZ的波形信号的控制字为X=655。

输出波形正好为一个周期1000ns。即1MHZ。

1024点FFT实信号输入。

FFTSHIFT频谱搬移模块

对于FFTSHIFT模块我们打开matlab帮助后可以发现,搬移的效果就是以频谱中心左右两端谱线互换。

ABS求平方根模块

求复数的模,定义为

复数\left | a+b*i \right |\sqrt{a^{2}+b^{2}}

在逻辑中我们使用cordic来计算平方根。

cordicIP配置如下所示

模块仿真

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/08/12 14:14:51
// Design Name: 
// Module Name: vtf_fft_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module vtf_fft_test;
//fft
//input
wire               [31:0] s_axis_data_tdata    ; 
wire                      s_axis_data_tvalid   ; 
wire                      s_axis_data_tready   ; 
wire                      s_axis_data_tlast    ; 
//output
wire               [31:0] m_axis_data_tdata    ; 
wire                      m_axis_data_tvalid   ; 
wire                      m_axis_data_tready   ; 
wire                      m_axis_data_tlast    ; 
wire               [23:0] m_axis_data_tuser    ; 

//dds
wire                      m_dds_tvalid         ; 
wire               [31:0] m_dds_tdata          ; 

//system signal
reg                       clk                  ; 
reg                       rst_n                ; 
reg                       data_gen             ; 
reg                       data_flog            ; 
reg                       douta_vld            ; 
reg                [15:0] cnt                  ; 

//fftshift
wire               [31:0] fftshift_data        ; // 
wire                      fftshift_data_valid  ; // 
wire                [9:0] fftshift_cnt         ; // 

//abs

wire               [15:0] abs_data             ; // (output)
wire                      abs_data_valid       ; // (output)
//system signal

//
assign  s_axis_data_tdata   = douta_vld ? m_dds_tdata : 32'h0;//给复信号
//assign  s_axis_data_tdata   = douta_vld ? {16'd0,m_dds_tdata[15:0]} : 32'h0;//实信号
assign  s_axis_data_tvalid  = douta_vld;
assign  s_axis_data_tlast   = (cnt == 16'd1023 );

assign  m_axis_data_tready  = 1'b1;

//FFT后数据
//取实部
wire               [15:0] f_imag               ; 
wire               [15:0] f_real               ; 
wire               [31:0] f_abs                ; 

assign  f_imag = m_axis_data_tdata[31:16];
assign  f_real = m_axis_data_tdata[15:0];
assign  f_abs  = f_imag + f_real;



//=========================================================
dds_compiler_0 u_dds (
    .aclk                         (clk                         ), // input wire aclk
    .s_axis_config_tvalid         (1'b1                         ), // input wire s_axis_config_tvalid
    .s_axis_config_tdata          (16'd655                      ), // input wire [15 : 0] s_axis_config_tdata
    .m_axis_data_tvalid           (m_dds_tvalid                 ), // output wire m_axis_data_tvalid
    .m_axis_data_tdata            (m_dds_tdata                  ), // output wire [31 : 0] m_axis_data_tdata
    .m_axis_phase_tvalid          (                             ), // output wire m_axis_phase_tvalid
    .m_axis_phase_tdata           (                             )// output wire [15 : 0] m_axis_phase_tdata
);

//=========================================================
xfft_0 u_fft (
    .aclk                         ( clk                         ), // input wire aclk
    .aresetn                      ( rst_n                       ), // input wire aresetn
    .s_axis_config_tdata          (8'd1                         ), // input wire [7 : 0] s_axis_config_tdata
    .s_axis_config_tvalid         (1'b1                         ), // input wire s_axis_config_tvalid
    .s_axis_config_tready         (                             ), // output wire s_axis_config_tready
    .s_axis_data_tdata            (s_axis_data_tdata            ), // input wire [31 : 0] s_axis_data_tdata
    .s_axis_data_tvalid           (s_axis_data_tvalid           ), // input wire s_axis_data_tvalid
    .s_axis_data_tready           (s_axis_data_tready           ), // output wire s_axis_data_tready
    .s_axis_data_tlast            (s_axis_data_tlast            ), // input wire s_axis_data_tlast
    .m_axis_data_tdata            (m_axis_data_tdata            ), // output wire [31 : 0] m_axis_data_tdata
    .m_axis_data_tuser            (m_axis_data_tuser            ), // output wire [23 : 0] m_axis_data_tuser
    .m_axis_data_tvalid           (m_axis_data_tvalid           ), // output wire m_axis_data_tvalid
    .m_axis_data_tready           (m_axis_data_tready           ), // input wire m_axis_data_tready
    .m_axis_data_tlast            (m_axis_data_tlast            ), // output wire m_axis_data_tlast
    .m_axis_status_tdata          (                             ), // output wire [7 : 0] m_axis_status_tdata
    .m_axis_status_tvalid         (                             ), // output wire m_axis_status_tvalid
    .m_axis_status_tready         (1'b1                         ), // input wire m_axis_status_tready
    .event_frame_started          (                             ), // output wire event_frame_started
    .event_tlast_unexpected       (                             ), // output wire event_tlast_unexpected
    .event_tlast_missing          (                             ), // output wire event_tlast_missing
    .event_status_channel_halt    (                             ), // output wire event_status_channel_halt
    .event_data_in_channel_halt   (                             ), // output wire event_data_in_channel_halt
    .event_data_out_channel_halt  (                             )// output wire event_data_out_channel_halt
);

//==========================================================
fft_shift u_fft_shift(
//
    .fft_data                     (m_axis_data_tdata            ), // (input ) 
    .fft_cnt                      (m_axis_data_tuser[9:0]       ), // (input ) 
    .fft_last                     (m_axis_data_tlast            ), // (input ) 
    .fft_data_valid               (m_axis_data_tvalid           ), // (input ) 
    .fftshift_data                (fftshift_data                ), // (output) 
    .fftshift_data_valid          (fftshift_data_valid          ), // (output) 
    .fftshift_cnt                 (fftshift_cnt[9:0]            ), // (output) 
//system signal
    .sys_clk                      (clk                          ), // (input ) 
    .rst_n                        (rst_n                        )// (input ) 
    );

//==========================================================
abs_top u_abs_top(
//
    .plural_data                  (fftshift_data[31:0]            ), // (input ) (input )
    .plural_data_valid            (fftshift_data_valid            ), // (input ) (input )
    .abs_data                     (abs_data[15:0]               ), // (output) (output)
    .abs_data_valid               (abs_data_valid               ), // (output) (output)
//system signal
    .clk                          (clk                          ), // (input ) (input )
    .rst_n                        (rst_n                        )  // (input ) (input )
);

//==========================================================
xfft_0 u_ifft (
    .aclk                         ( clk                         ), // input wire aclk
    .aresetn                      ( rst_n                       ), // input wire aresetn
    .s_axis_config_tdata          (8'd1                         ), // input wire [7 : 0] s_axis_config_tdata
    .s_axis_config_tvalid         (1'b1                         ), // input wire s_axis_config_tvalid
    .s_axis_config_tready         (                             ), // output wire s_axis_config_tready
    .s_axis_data_tdata            (m_axis_data_tdata            ), // input wire [31 : 0] s_axis_data_tdata
    .s_axis_data_tvalid           (m_axis_data_tvalid           ), // input wire s_axis_data_tvalid
    .s_axis_data_tready           (m_axis_data_tready           ), // output wire s_axis_data_tready
    .s_axis_data_tlast            (m_axis_data_tlast            ), // input wire s_axis_data_tlast
    .m_axis_data_tdata            (                             ), // output wire [31 : 0] m_axis_data_tdata
    .m_axis_data_tuser            (                             ), // output wire [23 : 0] m_axis_data_tuser
    .m_axis_data_tvalid           (                             ), // output wire m_axis_data_tvalid
    .m_axis_data_tready           (1'b1                         ), // input wire m_axis_data_tready
    .m_axis_data_tlast            (                             ), // output wire m_axis_data_tlast
    .m_axis_status_tdata          (                             ), // output wire [7 : 0] m_axis_status_tdata
    .m_axis_status_tvalid         (                             ), // output wire m_axis_status_tvalid
    .m_axis_status_tready         (1'b1                         ), // input wire m_axis_status_tready
    .event_frame_started          (                             ), // output wire event_frame_started
    .event_tlast_unexpected       (                             ), // output wire event_tlast_unexpected
    .event_tlast_missing          (                             ), // output wire event_tlast_missing
    .event_status_channel_halt    (                             ), // output wire event_status_channel_halt
    .event_data_in_channel_halt   (                             ), // output wire event_data_in_channel_halt
    .event_data_out_channel_halt  (                             )// output wire event_data_out_channel_halt
);

//================================================================
//================================================================
initial
begin
        clk = 0;
        rst_n=0;
        data_gen   =0;
        #100;
        rst_n      =1;
        #1000;
        data_gen   =1;
        #100;
        data_gen   =0;


end

always @ (posedge clk or negedge rst_n)
begin
        if(rst_n == 1'b0)begin         
                data_flog   <= 1'b0;
        end
        else if(data_gen == 1'b1)begin
                data_flog   <= 1'b1;
        end 
        else if(cnt   >= 10'd1022)begin
                data_flog   <= 1'b0;
        end
end

always @ (posedge clk or negedge rst_n)
begin
        if(rst_n == 1'b0)begin         
                douta_vld   <= 1'b0;
        end
        else begin
                douta_vld   <= data_flog;
        end 

end


always @ (posedge clk or negedge rst_n)
begin
        if(rst_n == 1'b0)begin         
                cnt <= 16'd0;
        end
        else if(s_axis_data_tvalid == 1'b1 && s_axis_data_tready == 1'b1)begin
                cnt <= cnt + 1'b1;
        end 
        else begin
                cnt <= cnt;
        end

end

//================================================================
//================================================================

always #5 clk = ~clk;

endmodule

复信号输入。

实信号输入。

逆傅里叶变换结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2046239.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

旧手机NAS方案

这里写目录标题 1、参考2、alpine-term-v16.0-release.apk下载安装3、电脑端ssh连接3、安装docker3.1 网络配置3.2 配置APK源 1、参考 【Docker与Termux】闲置旧安卓手机上的NAS无缝部署方案 https://blog.csdn.net/AnRanGeSi/article/details/138717589 【Alpine Term】Andr…

线程与进程(5)

目录 信号量&#xff08;线程的同步 &#xff09; 信号量的分类&#xff1a; 框架&#xff1a; &#xff08;1&#xff09;信号量的定义(semaphore): &#xff08;2&#xff09;信号量的初始化&#xff1a; &#xff08;3&#xff09;信号量的PV 操作 &#xff08;4&#…

Ubuntu Linux安装Go语言

Golang是Google公司在2007年开始开发的一种静态强类型、编译型语言。Go语言被设计成一门简单、高效且可靠的编程语言&#xff0c;旨在解决大规模网络服务和分布式系统开发中的复杂性问题。Go语言结合了动态语言的开发速度和C/C等编译型语言的性能与安全性&#xff0c;提供了强大…

[DL]深度学习_针对图像恢复的高效扩散模型DiffIR

DiffIR: Efficient Diffusion Model for Image Restoration Abstract 扩散模型(DM)通过将图像合成过程建模为去噪网络的顺序应用&#xff0c;实现了SOTA的性能。然而&#xff0c;与图像合成不同的是&#xff0c;图像恢复(IR)对生成符合ground-truth的结果有很强的约束。因此&am…

家穷就去互联网

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…

AI编程工具合集(附使用地址)

在AI编程工具领域&#xff0c;随着技术的飞速发展&#xff0c;越来越多的工具正在改变编程的方式。以下是目前排名前十的AI编程工具合集&#xff0c;提供了丰富的功能来提升开发效率&#xff0c;并在多个编程场景中帮助开发者解决问题。 1. GitHub Copilot • 是什么: GitHub C…

打靶笔记--medium_socnet

medium_socnet 靶机地址:https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 内容简介&#xff1a; 这是本系列的第04次打靶&#xff0c;我选择了一个中等难度的靶机。在这次打靶过程中&#xff0c;我们将使用到以下攻击手段&#xff1a; 主机发现 端口扫…

javaEE WebServlet、SpringWebMVC、SpringBoot实现跨域访问的4种方式及优先级,nginx配置跨域

文章目录 1. 前置知识2. 原理和解决方案总结2.1. 跨域不通过原理流程图2.2. 实现原理&#xff1a;添加以下http响应头2.3. 四种跨域实现方式及优先级&#xff08;从高到低&#xff09; 3. 具体实现代码3.1. 跨域全局配置方式-Filter(全适用)3.2. 跨域全局配置方式-SpringMvc3.3…

鸿蒙内核源码分析(内存规则篇) | 内存管理到底在管什么

先说如果没有内存管理会怎样? 那就是个奴才们能把主子给活活踩死&#xff0c; 想想主奴不分&#xff0c;吃喝拉撒睡都在一起&#xff0c;称兄道弟的想干啥? 没规矩不成方圆嘛&#xff0c;这事业肯定搞不大&#xff0c;单片机时代就是这种情况. 裸机编程&#xff0c;指针可以…

【笔记】MSPM0G3507使用RT-Thread FinSH——MSPM0G3507与RT_Thread(四)

接上篇 KEIL 添加 FinSH 源码 添加自己的函数实现rt_hw_console_getchar 修改为&#xff1a; #include "C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\G3507_RTT\ti_msp_dl_config.h"//ti_msp_dl_config.h的绝对地址RT_WEAK char rt_hw_con…

Java知识点一——列表、表格与媒体元素

显示表格边框&#xff1a;<table border"1"></table> 因为初始的表格是没有边框的 collapse相邻的单元格共用同一条边框&#xff08;采用 collapsed-border 表格渲染模型&#xff09;。 separate默认值。每个单元格拥有独立的边框&#xff08;采用 sep…

Haskell爬虫中日志记录:监控HTTP请求与响应

在当今信息爆炸的时代&#xff0c;数据抓取成为了获取信息的重要手段。Haskell&#xff0c;以其强大的类型系统和函数式编程特性&#xff0c;成为了编写高效、可靠爬虫的理想选择。然而&#xff0c;随着爬虫的运行&#xff0c;监控其行为变得尤为重要。本文将探讨如何在Haskell…

ROS2从入门到精通2-4:Rviz2插件制作案例(以工具栏和多点导航插件为例)

目录 0 专栏介绍1 Rviz2插件2 项目配置3 案例一&#xff1a;工具栏插件4 案例二&#xff1a;多点导航插件5 综合演示5.1 添加插件5.2 多点巡航 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS2进行实…

企业图纸防泄密的最佳方案,10款好用的图纸加密软件排行榜

在数字化时代&#xff0c;企业的图纸文件往往包含了极其重要的知识产权和技术秘密&#xff0c;因此保护这些图纸的安全至关重要。有效的图纸加密不仅能防止未授权访问&#xff0c;还能确保图纸在内外部流转过程中的完整性与安全性。本文将介绍十款2024年市场上评价较高的图纸加…

基于Mysql的商业辅助决策系统的设计与实现

TOC springboot295基于Mysql的商业辅助决策系统的设计与实现 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们…

零-STM32与嵌入式

目录 一、嵌入式概述 二、微控制器的关系 三、STM32的学习原因 四、STM32的应用领域 五、STM32的就业前景 六、STM32开发方式 (1) 寄存器开发&#xff08;自己做饭&#xff0c;自己吃&#xff09; (2) 函数库开发&#xff08;别人做饭&#xff0c;自己吃&#xff09; …

喜报 亚信安全再次入选湖北省网络安全应急技术支撑单位

近日&#xff0c;中共湖北省委网络安全和信息化委员会办公室和国家计算机网络应急技术处理协调中心湖北分中心公布了《关于开展第二届湖北省网络安全应急技术支撑单位评选工作的通知》&#xff0c;亚信安全凭优秀的产品技术实力和丰富的安全服务实践经验&#xff0c;连续两届成…

调研适合c++训练和部署的框架

目录 1. caffe 2. TensorFlow 3. Pytorch 4. PaddlePaddle 5. darknet 1. caffe GitHub - BVLC/caffe: Caffe: a fast open framework for deep learning. Caffe (Convolutional Architecture for Fast Feature Embedding) Caffe是一个早期流行的深度学习框架&#xff0…

GreptimeDB融资数百万美元; Oracle提供免费长期MySQL; 谷歌大模型支持云数据库问题洞察

重要更新 1. 开源时序数据库 GreptimeDB宣布完成数百万美元的新一轮融资。GreptimeDB是一款Rust 语言编写的时序数据库&#xff0c;具有分布式&#xff0c;开源&#xff0c;云原生&#xff0c;兼容性强等特点&#xff0c;帮助企业实时读写、处理和分析时序数据的同时&#xff0…

Linux设备驱动——模块的构造、运行与设计 与众不同的hello world与点灯

编写一个Linux下的设备驱动&#xff0c;首先要准备好对应内核版本的内核源码树文件。 该系列的全部文章都以嵌入式系统的ARM-Linux的环境进行阐述&#xff0c;并以交叉编译的方式在主机Ubuntu20.04系统上编译和ARM开发板上跑测 (E2000Q、H616、或者IMX6ULL看情况交叉着使用) 关…