vivado FFT IP核使用

matlab生成正弦函数

采样点数为512,每个采样点位宽为16位,其中最高位为符号为(0正,1负)。换句话说,如果用ROM存储正弦函数的coe文件的话,ROM ip核的位宽设置为16,深度为512.

clear all;Fs = 512;
t = 0:1/Fs:1-1/Fs;
y = sin(10*t);            %产生正弦波,总点数为512点
y_16bit = floor(y*2^15);  %把数据量化为15位,因为要留一个符号位subplot(221);
plot(y_16bit);
xlabel('原始有符号数的正弦波形');y1 = fft(y_16bit,512);
subplot(222);
plot(real(y1));
xlabel('原始有符号数的fft(实部)');y_16bit_a = y_16bit;   %定义相同大小的变量,存储转变符号后的数据
%下面for循环的目的是将原本的负数变为正数(在最高位加上符号位),便于vivado读取
for i = 1:length(y_16bit)if( y_16bit_a(i) < 0 )y_16bit_a(i) = 2^16+y_16bit_a(i);%当信号小于零时,通过将其与 2^16 相加,可以确保最高位为1,从而表示该数字是一个负数endendsubplot(223);
plot(y_16bit_a);
xlabel('将有符号数转化为无符号数的正弦波形');y2 = fft(y_16bit_a,512);subplot(224);
plot(real(y2));
xlabel('转化为无符号数后的fft(实部)');fid = fopen('sinwave.txt','w');   %将转变符号后的数据写入文件中,等到vivado读取
fprintf(fid,'%x\r\n',y_16bit_a);

注意: 我们要确保输出给fft ip核的数据是16位,同时最高位是符号位,因此我们将原始数据乘上2的15次方填满低15位,在将负数加上2的16次方使得最高位为1。在我们写入txt时,我们是以%x(16进制写入的)因此正数最高位自动补0,负数保持不变,这样就确保了16bit输入,同时正数最高位为0,负数最高位为1

vivado FFT ip核使用

ip核的配置

 

此时我们看一下FFT ip核的信息

从图上可以知道,该FFT ip核在完成512次fft计算后会经过3476次时钟周期,一次时钟周期时4ns,因此一共延迟13868ns=13.868us

FFT ip核的例化 

顶层文件如下

`timescale 1ns / 1ps
module fft_top(input [15:0]data_in,input clk,input data_last,input data_valid,output out_valid,output [31:0]out_im,output [31:0]out_re);wire [63:0]fft_out;xfft_0 test (.aclk(clk),                                                 // input wire aclk                         (输入时钟).s_axis_config_tdata(16'd1),                                // input wire [15 : 0] s_axis_config_tdata(配置数据,1为FFT,0为IFFT).s_axis_config_tvalid(1'd1),                                // input wire s_axis_config_tvalid        (1则开始进行FFT配置,0停止).s_axis_config_tready(),                                    // output wire s_axis_config_tready       (输出:当FFT配置好时,会给标志).s_axis_data_tdata({16'd0,data_in}),                        // input wire [31 : 0] s_axis_data_tdata   (输入数据,高n位为虚部,低n位为实部).s_axis_data_tvalid(data_valid),                             // input wire s_axis_data_tvalid          (1则开始进行FFT计算,0停止).s_axis_data_tready(),                                      // output wire s_axis_data_tready         .s_axis_data_tlast(data_last),                               // input wire s_axis_data_tlast           (最后一个数据标志位,便于结束FFT).m_axis_data_tdata(fft_out),                                // output wire [63 : 0] m_axis_data_tdata  (FFT的输出值).m_axis_data_tvalid(out_valid),                             // output wire m_axis_data_tvalid.m_axis_data_tuser(),                                       // output wire [15 : 0] m_axis_data_tuser.m_axis_data_tready(1'd1),                                  // input wire m_axis_data_tready 一直置1即可           .m_axis_data_tlast(),                                       // output wire m_axis_data_tlast.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
);assign out_im = fft_out[63:32];assign out_re = fft_out[31:0];endmodule

FFT ip核的例化详见:Vivado IP核:FFT实验 - 知乎 (zhihu.com) 

TestBench文件编写

`timescale 1ns / 1ps
module fft_tb();reg  [15:0] data_temp [0:511]; reg  [15:0] data_input;reg clk;reg data_last;reg data_valid;wire [31:0]out_im;wire [31:0]out_re;wire out_valid;reg [31:0]reg_out_im;reg [31:0]reg_out_re;integer i;integer fid_out_re;integer fid_out_im;always #2 clk <= ~clk; //生成时钟///例化代码fft_top bidesign_top1(.data_in(data_input),.clk(clk),.data_last(data_last),.data_valid(data_valid),.out_valid(out_valid),.out_im(out_im),.out_re(out_re));///initial beginclk        <= 1'd1;data_input   <= 16'd0;data_valid  <= 1'b0;data_last   <= 1'b0;$readmemh("E:/FPGA/book/vivado/FPGA_DSP/project_FFT_ip/matlab/sinwave.txt",data_temp); //读文件fid_out_re = $fopen("E:/FPGA/book/vivado/FPGA_DSP/project_FFT_ip/matlab/out_re.txt","w"); fid_out_im = $fopen("E:/FPGA/book/vivado/FPGA_DSP/project_FFT_ip/matlab/out_im.txt","w");#10; //延迟2.5个时钟周期     for(i = 0;i<=511;i = i+1)begindata_valid <= 1;data_input  <= data_temp[i];#4;//延迟一个时钟周期enddata_last  <= 1;data_valid <= 0;data_input <= 16'd0;       #2000;endalways @ (posedge clk) begin    $fwrite(fid_out_re,"%d\n",$signed(reg_out_re[31:0])); $fwrite(fid_out_im,"%d\n",$signed(reg_out_im[31:0]));               endalways @ (posedge clk) begin                //fft输出结果到寄存器中保存,使数据更稳定reg_out_im <= out_im;reg_out_re <= out_re;endalways @ (posedge clk) beginif(!out_valid) begin    reg_out_re <= 32'd0;reg_out_im <= 32'd0;endend
endmodule

值得注意的点:输入fft的数据是在 clk(系统时钟)的上升沿读取的,如果数据也是在clk上升沿更新的话可能会出现亚稳态,因此我们通过时延半个周期使得数据在中间位置(即 clk 的下降沿)被fft读取时才是相对稳定的。在代码中#10确保了data_input在下降沿更新,#4确保了数据更新周期与时钟周期保持一致,这样就确保了FFT读取data_input时data_input信号是稳定的。

时序分析

注意:data_input的格式调整为unsigned/analog下的曲线 

接下来我们分析每个信号的变化关系

注意:data_input也是延迟10ns后开始变化的,但是由于data_input初始值为0,所以在10~14ns的时间内任然保持0

接下来我们重点分析FFT的输出信号:out_re和out_im 

out_re是延迟了11828ns输出结果,out_im是延迟了11832ns输出结果,它们分别对应延迟了11828/4=2957和11832/4=2958个时钟周期。除此之外,可以发现reg_out_im和reg_out_re滞后out_im和out_re一个时钟周期,这也是时序逻辑赋值产生的延迟

out_re和out_im在延迟了13876ns后输出完成,一共延迟了13876/4=3469个时钟周期,减去初始化的2.5个之中周期后,延迟结果与FFT ip核的信息给出的结果保持一致。

Matlab 数据分析

我们将vivado输出的FFT ip核的fft 实部虚部结果的txt文件导入matlab

matlab导入txt代码如下:

clear all;
present_re=importdata('out_re.txt');
present_im=importdata('out_im.txt');% 找到非零值的索引
nonzero_indices_re = find(present_re.data ~= 0);% 提取非零值对应的元素
re = present_re.data(nonzero_indices_re);plot(re);

我们只需要去其实部即可:

 与matlab结果保持一致。验证了我们的工作正确性

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

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

相关文章

Vue ElementUI el-input-number 改变控制按钮 icon 箭头为三角形

el-input-number 属性 controls-position 值为 right 时&#xff1b; <el-input-number v-model"num" controls-position"right" :min"1" :max"10"></el-input-number>原生效果 修改后效果 CSS 修改 .el-input-number…

STM32电机控制SDK介绍

目录 一、STM32 MC SDK包含以下项目&#xff1a; 二、电机控制应用流程 三、 MC 软件应用程序设计工作流程 四、STM32 MC固件 五、PMSM FOC 库 一、STM32 MC SDK包含以下项目&#xff1a; STM32 MC firmwareSTM32 MC WorkbenchSTM32 MC Board ManagerSTM32 Motor PilotTh…

项目从 Mysql切换 PostgreSQL 改造及踩坑记录

0、前言 原项目框架 SpringBoot MybatisPlus Mysql 1、切换流程 1.1、项目引入postgresql驱动包 由于我们要连接新的数据库&#xff0c;理所当然的要引入该数据库的驱动包&#xff0c;这与mysql驱动包类似 <dependency><groupId>org.postgresql</groupId…

MongoDB常用命令总结

《【快捷部署】017_MongoDB&#xff08;6.0.14&#xff09;》 讲述了如何快捷部署MongoDB&#xff0c;今天我们来总结一下MongoDB常用的shell命令。 一、基本操作&#xff08;CRUD&#xff09; #创建集合&#xff0c;名为 users db.createCollection("users")# 插入…

免费搭建幻兽帕鲁服务器(Palworld免费开服教程)

随着互联网技术的不断发展和普及&#xff0c;网络游戏已经成为了人们休闲娱乐的重要方式之一。而在众多网络游戏中&#xff0c;幻兽帕鲁以其独特的游戏设定和玩法&#xff0c;吸引了大量玩家的关注。为了满足广大玩家的需求&#xff0c;本文将介绍如何免费搭建幻兽帕鲁服务器&a…

Green Hills 自带的MULTI调试器查看R7芯片寄存器

Green Hills在查看芯片寄存器时需要导入 .grd文件。下面以R7为例&#xff0c;演示一下过程。 首先打开MULTI调试器&#xff0c;如下所示View->Registers&#xff1a; 进入如下界面&#xff0c;选择导入寄存器定义文件.grd&#xff1a; 以当前R7芯片举例&#xff08;dr7f7013…

Python+Appium自动化测试(ios+Android)

一、软件安装 安装清单&#xff1a; JDKPythonnode.jsandroid-sdk(作者通过Android Studio安装)iOS-deploybrewlibimobiledevice依赖库ideviceinstallercarthage依赖库 appium-doctor&#xff08;安装后可在命令行中通过命令:appium-doctor检查还少啥&#xff09; WebDriverAg…

应急响应-战中反制对抗上线CSGoby蚁剑Sqlmap等安全工具

知识点 战中-反制-安全工具篇CS反制(有版本限制) Goby反制&#xff08;有版本限制&#xff0c;新版goby已修复&#xff09; Antsword反制(有版本限制&#xff0c;别人也不一定用蚁剑) AWVS反制(有版本限制&#xff0c;在awvs 10版本存在&#xff09; BURP反制(有版本限制&…

基于python的天气数据可视化系统、Flask框架,爬虫采集天气数据,可视化分析

系统介绍 基于Python的天气预测可视化分析系统&#xff0c;该项目的主要流程和功能包括&#xff1a; 数据获取&#xff1a; 使用Python的pandas库从2345天气网&#xff08;http://tianqi.2345.com/Pc/GetHistory&#xff09;抓取山东省各市区县在2021年至2023年间的天气历史数…

C语言 | Leetcode C语言题解之第21题合并两个有序链表

题目&#xff1a; 题解&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/typedef struct ListNode ListNode; struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {/…

钉钉和金蝶云星空接口对接实战

钉钉和金蝶云星空接口对接实战 对接源平台:钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团打造的企业级智能移动办公平台&#xff0c;是数字经济时代的企业组织协同办公和应用开发平台。钉钉将IM即时沟通、钉钉文档、钉闪会、钉盘、Teambition、OA审批、智能人事、钉…

django 模板js文件为什么最后引入

<!-- 引入Bootstrap JS --> <script src"https://cdn.jsdelivr.net/npm/bootstrap5.3.0/dist/js/bootstrap.bundle.min.js"></script> 为什么最后引入例子 <!-- templates/inspection_records.html --><!DOCTYPE html> <html lang…

ShardingSphere再回首

概念&#xff1a; 连接&#xff1a;通过协议 方言及库存储的适配&#xff0c;连接数据和应用&#xff0c;关注多模数据苦之间的合作 增量&#xff1a;抓取库入口流量题提供重定向&#xff0c; 流量变形(加密脱敏)/鉴权/治理(熔断限流)/分析等 可插拔&#xff1a;微内核 DDL:cr…

2024最新AI系统【SparkAI】,ChatGPT商业运营版系统源码/ai问答/ai绘画/GPTs,SunoAI音乐生成大模型/带分销AIGC搭建部署教程

一、文章前言 SparkAi创作系统是基于ChatGPT进行开发的ai智能问答系统和Midjourney-AI绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已…

MySQL进阶一

目录 1.使用环境 2.条件判断 2.1.case when 2.2.if 3.窗口函数 3.1.排序函数 3.2.聚合函数 ​​​​​​​3.3.partiton by ​​​​​​​3.4.order by 4.待续 1.使用环境 数据库&#xff1a;MySQL 8.0.30 客户端&#xff1a;Navicat 15.0.12 2.条件判断 2.1.ca…

手机银行客户端框架之EMAS介绍

EMAS简介 阿里巴巴应用研发平台&#xff08;Enterprise Mobile Application Studio&#xff0c;简称EMAS&#xff09;&#xff0c;是面向全端场景&#xff08;移动App、H5应用、小程序、Web应用、PC应用等&#xff09;的一站式应用研发平台。EMAS基于广泛的云原生技术&#xf…

5G智慧港口简介(一)

引言 港口作为交通运输的枢纽,在促进国际贸易和地区发展中起着举足轻重的作用,全球贸易中约 90% 的贸易由海运业承载,作业效率对于港口至关重要。在“工业 4.0”、“互联网 +”大发展的时代背景下,港口也在进行数字化、全自动的转型升级。随着全球 5G 技术浪潮的到来,华为…

用国内版Devin:DevOpsGPT开发一个简易官网

前言&#xff1a; 世界上第一个AI程序员Devin想必已经给大家带来了不小的震撼&#xff0c;这种L4级的技术也许已经昭示着AGI离我们或许真的不远了。 这里先给大家普及一个概念&#xff1a; L4是谷歌对AGI划分的第四个等级&#xff0c;把代码丢给 AI 改这个是 L1 或者 L2 级别的…

【精品PPT】智慧路灯大数据平台整体建设实施方案(免费下载)

1、知识星球下载&#xff1a; 如需下载完整PPTX可编辑源文件&#xff0c;请前往星球获取&#xff1a;https://t.zsxq.com/19QeHVt8y 2、免费领取步骤&#xff1a; 【1】关注公众号 方案驿站 【2】私信发送 【智慧路灯大数据平台】 【3】获取本方案PDF下载链接&#xff0c;直…

实战项目——智慧社区(三)之 门禁管理

1、人脸识别 实现思路 ①查询出所有的小区信息&#xff0c;下拉列表显示&#xff0c;用于后续判断人脸信息是否与所选小区匹配 ②人脸识别&#xff1a;调用腾讯人脸识别的API接口&#xff0c;首先判断传入图片是否为一张人脸&#xff1b;其次将这张人脸去服务器的人员库进行…