当前位置: 首页 > news >正文

AD7606 FFT 频谱分析 FPGA 设计 Verilog Vivado VHDL

名称:AD7606 FFT 频谱分析 FPGA 设计 Verilog Vivado VHDL

软件:Vivado

语言:VHDL

功能介绍

本设计面向 AD7606 采样数据的 FPGA 频谱分析应用,将外部 ADC 输入的 16bit 采样数据送入缓存,再按固定点数组织为一帧 FFT 输入数据,通过 Xilinx FFT IP 完成频域转换,最终根据 FFT 输出结果计算频谱幅值并提取最大幅值对应的频率信息。 核心控制模块为 FFT_ctrl,接口包含 50MHz 时钟、复位、AD 采样数据有效标志、16bit 采样数据输入以及最大频率输出。设计中通过 point 参数设置 FFT 点数,通过 resolve 参数设置频率分辨率相关换算系数,便于根据实际采样率和 FFT 点数调整频率计算方式。 数据处理流程比较清晰:ADC 数据先写入 FIFO,当 FIFO 满足一帧数据条件后再读出送入 FFT IP;FFT 输出的实部和虚部分别取出后进行平方和计算,用于幅值比较;在 FFT 输出有效期间统计频点序号,并记录最大幅值对应的位置,从而得到主要频率成分。该设计适合用于 AD7606 数据采集后的频谱观察、主频检测、信号分析等 FPGA 实验或工程参考。

运行环境

开发软件:Vivado。 设计语言:Verilog。 主要 IP:Xilinx FFT IP、FIFO Generator IP。 工程文件包含 Vivado 工程、约束文件、仿真相关文件以及 IP 静态库文件,适合在 Vivado 环境中综合、实现和仿真参考。

设计思路

设计采用“采样缓存 + 分帧读取 + FFT 运算 + 幅值比较”的结构。AD7606 输出的 16bit 采样数据并不是直接连续送入 FFT,而是先进入 FIFO 进行缓存;当 FIFO 写满后,控制逻辑启动读使能,将一帧数据按时钟节拍送入 FFT IP。这样可以保证 FFT 输入数据帧完整,便于与 IP 核的 AXI-Stream 时序配合。 FFT 输入端使用 s_axis_data_tvalid 指示当前数据有效,并通过 last 信号标记一帧输入数据的最后一个点。FFT 配置通道保持有效,数据通道将采样数据作为实部输入,虚部补零,适用于实数采样信号的频域分析。FFT 输出端通过 m_axis_data_tvalid 判断频域数据是否有效,输出数据被拆分为实部和虚部,后续逻辑对二者进行平方和计算,得到可用于比较的幅值能量值。 最大频点提取部分在 FFT 输出有效期间进行计数,计数值代表当前频点位置;同时比较当前幅值平方和与历史最大值,记录最大幅值对应的频点编号,再结合频率分辨率参数换算输出频率。由于参数 point 与 resolve 在源码中给出,使用时可以根据实际采样时钟和 FFT 点数进行调整,从而适配不同采样条件。

模块结构

主要模块包括: AD_FFT_top:顶层相关模块,用于连接 AD7606 采样接口与 FFT 处理控制逻辑。 ad7606_if:AD7606 接口相关逻辑,用于配合 ADC 采样数据输入。 FFT_ctrl:FFT 控制核心模块,负责 FIFO 写入/读取控制、FFT IP 数据输入、FFT 输出拆分、幅值平方和计算以及最大频点输出。 testbench:仿真测试模块,用于 Vivado 仿真环境下验证逻辑连接和时序行为。 fifo_65536:FIFO Generator IP,用于缓存采样数据并按帧向 FFT 模块供数。 xfft_point / xfft_65536:Xilinx FFT IP 相关模块,用于完成频域转换。

开发板验证

工程带有 AD7606 相关管脚约束文件 ad7606_pins_test.xdc,并在 Vivado 工程约束目录中配置了对应约束。约束文件可作为开发板实际连线和管脚分配参考,适合在匹配硬件连接条件下进行板级综合、实现和下载验证。 由于约束中已经体现 AD7606 接口的管脚分配,使用时需要结合实际 FPGA 开发板原理图核对时钟、复位、ADC 数据线及控制信号连接,确认电平标准和引脚位置一致后再进行板级测试。

仿真图/仿真说明/设计文档图片

设计配套 Vivado 行为仿真工程目录,并提供 testbench 模块,可用于观察 FIFO 控制、FFT 输入有效信号、FFT 输出有效信号及频点计数等关键时序。仿真时可重点关注 wr_data_vld、wr_en、rd_en、valid、last、fft_dout_tvalid、fft_dout_re、fft_dout_im、fre_cnt 和 max_data 等信号。

部分代码

以下展示顶层模块FFT_ctrl的部分代码,完整代码可关注下方公众号卡片获取。

module FFT_ctrl( input clk,//时钟50M input rst_p,//复位 input wr_data_vld,//数据有效标志 input [15:0] wr_data,//AD采样的16bit数据 output [36:0] max_data//最大值对应的频率 ); parameter point=16384;//根据实际点数修改 parameter resolve=12207;//200_000*1000/point=频率分辨率*1000,采样时钟除以点数,根据实际点数修改 //fifo 空满信号 wire empty; wire almost_empty; wire full; reg wr_en=0;//fifo 写使能 reg rd_en=0;//fifo 读使能 wire [15:0] rd_data;//fifo 读数据 wire last;//FFT输入的最后一个数 reg valid=0;//FFT输入数据有效指示 wire [31:0] fft_dout;//FFT输出 wire fft_dout_tvalid;//FFT输出数据有效指示 (* MARK_DEBUG="true" *)wire signed [15:0] fft_dout_re;//FFT输出数据实部 wire signed [15:0] fft_dout_im;//FFT输出数据虚部 always@(posedge clk or posedge rst_p) if(rst_p)//复位 wr_en<=0; else if(empty==1)//FIFO空时开始写 wr_en<=1; else if(full==1)//FIFO满时停止写 wr_en<=0; always@(posedge clk or posedge rst_p) if(rst_p)//复位 rd_en<=0; else if(full==1 && fft_dout_tvalid==0)//FIFO存满,且FFT IP核处于空闲状态 rd_en<=1;//读使能 else if(almost_empty==1)//将空时 rd_en<=0;//关闭读使能 always@(posedge clk or posedge rst_p) if(rst_p)//复位 valid<=0; else if(rd_en==1)//读使能 valid<=1;//FFT输入数据有效指示 else valid<=0; assign last=valid & empty;//FFT输入的最后一个数 wire [13 : 0] data_count; //调用point点FIFO IP核 fifo_65536 i_fifo_point ( .clk(clk), // input wire clk .srst(rst_p), // input wire srst .din(wr_data), // input wire [15 : 0] din .wr_en(wr_en & wr_data_vld), // input wire wr_en .rd_en(rd_en), // input wire rd_en .dout(rd_data), // output wire [15 : 0] dout .full(full), // output wire full .empty(empty), // output wire empty .almost_empty(almost_empty), // output wire almost_empty .data_count(data_count) // output wire [13 : 0] data_count ); assign fft_dout_re=fft_dout[15:0];//FFT输出数据实部 assign fft_dout_im=fft_dout[31:16];//FFT输出数据虚部 //调用65536点FFT IP核 xfft_point i_xfft_point ( .aclk(clk), // input wire aclk .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({16'd0,rd_data}), // input wire [31 : 0] s_axis_data_tdata .s_axis_data_tvalid(valid), // input wire s_axis_data_tvalid .s_axis_data_tready(), // output wire s_axis_data_tready .s_axis_data_tlast(last), // input wire s_axis_data_tlast .m_axis_data_tdata(fft_dout), // output wire [31 : 0] m_axis_data_tdata .m_axis_data_tuser(), // output wire [7 : 0] m_axis_data_tuser .m_axis_data_tvalid(fft_dout_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 ); wire signed [31:0] Sum; assign Sum=fft_dout_re*fft_dout_re+fft_dout_im*fft_dout_im;//实部虚部平方和 reg signed [31:0] Sum_Max; (* MARK_DEBUG="true" *)reg [13:0] fre_cnt=14'd0; reg [15:0] MAX_cnt=16'd0; always@(posedge clk or posedge rst_p) begin if(rst_p)//复位 fre_cnt<=14'd0; else if(fft_dout_tvalid==1)//FFT输出数据有效指示 fre_cnt<=fre_cnt+14'd1;//FFT输出个数计数 else fre_cnt<=14'd0; end //always@(posedge clk or posedge rst_p) // ... 以下代码略,完整源码请下载压缩包查看

代码获取:点击下方公众号卡片

http://www.gsyq.cn/news/1556871.html

相关文章:

  • 苏州家具安装推荐良匠千艺2026口碑榜 - 我叫一
  • 2026昆山防水修缮案例适配指南:以鼎壹万为核心的本地服务商场景化专业解析 专业防水公司排名推荐(2026年6月防水补漏最新TOP权威排名) - 鼎壹万修缮说
  • 机器学习——Day02
  • 【解构】GE-GAN:图嵌入与生成对抗网络如何重塑城市交通感知
  • 第18章:Scheduler 与连续批处理机制
  • 2026昆山家庭防水修缮市场深度分析及3家适配服务商测评 专业防水公司排名推荐(2026年6月防水补漏最新TOP权威排名) - 鼎壹万修缮说
  • 第8章:50个生产级Prompt模板库——按场景分类,拿来就用
  • 17种创意主题:用代码绘制你的城市艺术名片
  • 爱回收买二手苹果靠谱吗?我拆了质检流程给你看 - 新闻快传
  • Python-docx实战:深度解析Word段落样式与字体的继承机制
  • Logstash:从Syslog到Elasticsearch的日志管道实战解析
  • BG3ModManager完整使用指南:博德之门3模组管理终极教程
  • 2026烟台非急救转运救护车TOP5盘点|烟威同城、跨海跨岛、昆嵛山山地、院区转诊首选康跃转运 - 吉修匠
  • 如何构建突破性的实时弹幕采集系统:抖音直播数据抓取的3大创新技术解密
  • 深耕贵阳防水领域,匠心守护林城安居 微顺虹防水初心筑品质,服务护林城万家 - 徽顺虹
  • 2026昆山外墙渗水修缮行业适配指南:本地服务商适配推荐与选型解析 专业防水公司排名推荐(2026年6月防水补漏最新TOP权威排名) - 鼎壹万修缮说
  • 储能系统网络合规架构:基于本地隔离与安全中继的边缘侧实战
  • 西安家具安装推荐良匠千艺2026口碑榜 - 我叫一
  • 成都家具安装推荐良匠千艺2026口碑榜 - 我叫一
  • Python办公01:一键合并多文件夹下百份 Excel 自动汇总至总表
  • 深耕盐城防水领域,匠心守护盐渎安居 微顺虹防水初心筑品质,服务护鹤城万家 - 徽顺虹
  • 从“手工作坊“到“智能工厂“:商业卫星制造的革命性转型
  • 2026年湖北百合种植及种苗产业解析,百合龙头企业权威榜单,四叶参/百合哪家专业 - 新闻快传
  • 爱回收买iWatch靠谱吗?测评博主的一份功课清单 - 新闻快传
  • 语音深度伪造检测:四分类框架解决误判难题
  • 孩子有必要早教么?我纠结了四年,买奇多多后才敢给你标准答案。 - 新闻快传
  • 绘本机有必要买吗?看完奇多多的真实能力,我把选择标准推倒重来 - 新闻快传
  • 从零到一:手把手构建你的第一个浅层神经网络
  • 广州家具安装推荐良匠千艺2026口碑榜 - 我叫一
  • 二手平台哪个更靠谱?2026年四大平台实测,从质检到定价逐项拆解 - 新闻快传