FPGA数字频率合成器及fir滤波器设计(利用vivado dds、fir ip核)

2024-02-23 06:50

本文主要是介绍FPGA数字频率合成器及fir滤波器设计(利用vivado dds、fir ip核),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

工作任务

1.逻辑使用200MHz时钟做参考,做一个DDS数字频率合成器产生1MHz、10MHz和50MHz的正弦波,然后相加得到一个三音正弦波形。\
2.然后用MATLAB设计一个带通FIR滤波器,16bit量化,导出抽头文件,在FPGA上实现,对前面的三音信号进行带通滤波,滤掉1MHz和50MHz频率,得到一个10MHz的正弦波。\
3.编写TestBench对工程进行仿真,并在米联客7035开发板上综合运行,使用内置逻辑分析仪观察信号波形。

设计方案

1.倍频–clking winzard ip核(100Mhz–>200Mhz)\
2.dds adder3模块(调用dds ip核产生1MHz、10MHz和50MHz的正弦波,并合成)\
3.fir ip模块(带通FIR滤波)\
4.tb仿真\
5.ILA板级验证

实验流程

MATLAB——滤波器设计

在这里插入图片描述
Simulation–testbench 仿真结果
在这里插入图片描述
在这里插入图片描述
Simulation–ILA 板级仿真
在这里插入图片描述

具体过程

1.米联客7035开发板的晶振为100Mhz,而实验要求为200Mhz,所以需要调用时钟ip核进行倍频

clk_wiz_double u_clk_wiz_double(// Clock out ports.clk_out1(clk),     // output clk_out1// Clock in ports.clk_in1(sys_clk));      // input clk_in1

在这里插入图片描述
2.调用dds ip核进行频率合成,分别产生1MHz、10MHz和50MHz的正弦波

dds_1mhz u_dds_1mhz (.aclk(clk),                              // input wire aclk//.m_axis_data_tvalid(data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(sin_1mhz)    // output wire [7 : 0] m_axis_data_tdata
);dds_10mhz u_dds_10mhz (.aclk(clk),                              // input wire aclk//.m_axis_data_tvalid(data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(sin_10mhz)    // output wire [7 : 0] m_axis_data_tdata
);dds_50mhz u_dds_50mhz (.aclk(clk),                              // input wire aclk//.m_axis_data_tvalid(data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(sin_50mhz)    // output wire [7 : 0] m_axis_data_tdata
);

在这里插入图片描述
3.构建加法器进行三音合成,有符号数相加为防止溢出需进行符号位扩展

always@(posedge clk )beginsin_add = {{2{sin_1mhz[7]}},sin_1mhz} + {{2{sin_10mhz[7]}},sin_10mhz} + {{2{sin_50mhz[7]}},sin_50mhz};end

4.利用matlab进行fir滤波器参数设计,导出coe文件。利用vivado fir ip核进行滤波器设计,fir滤波器输入为16位,所以需要对三音合成后的10位输出进行符号位扩展。

always @(posedge clk) beginfir_in = {{6{fir_in_10[9]}},fir_in_10};
endassign 	s_axis_data_tvalid = 1'b1;fir_dds_adder3 u_fir_dds_adder3 (.aclk(clk),                              // input wire aclk.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_tdata(fir_in),    // input wire [15 : 0] s_axis_data_tdata//.m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(fir_out)    // output wire [31 : 0] m_axis_data_tdata
);

在这里插入图片描述
在这里插入图片描述
5.后续进行testbench仿真,调用ila ip核进行板级验证。

ila_0 u_ila_0 (.clk(clk), // input wire clk.probe0(sys_clk), // input wire [0:0]  probe0  .probe1(sin_1mhz), // input wire [7:0]  probe1 .probe2(sin_10mhz), // input wire [7:0]  probe2 .probe3(sin_50mhz), // input wire [7:0]  probe3 .probe4(sin_add), // input wire [9:0]  probe4 .probe5(fir_out) // input wire [31:0]  probe5
);

程序代码

代码详情分为三个模块:
1.top模块

`timescale 1ns / 1psmodule top_dds_fir(
input	sys_clk
//output wire	clk,
//output wire	[7:0]	sin_1mhz,sin_10mhz,sin_50mhz,
//output wire	[9:0]	sin_add,
//output wire	[31:0]	fir_out,
//output wire	[9:0]	fir_in_10);wire	clk;
wire	[7:0]	sin_1mhz,sin_10mhz,sin_50mhz;
wire	[9:0]	sin_add;
wire	[31:0]	fir_out;
//wire	[9:0]	fir_in_10;dds_adder3  u_dds_adder3(
.clk		(clk)       ,
.sin_1mhz   (sin_1mhz)	,
.sin_10mhz  (sin_10mhz)	,
.sin_50mhz  (sin_50mhz)	,
.sin_add    (sin_add)	);fir_ip u_fir_ip(
.clk			(clk		),
.fir_in_10		(sin_add	),
.fir_out		(fir_out	));//assign fir_in_10 = sin_add;clk_wiz_double u_clk_wiz_double(// Clock out ports.clk_out1(clk),     // output clk_out1// Clock in ports.clk_in1(sys_clk));      // input clk_in1ila_0 u_ila_0 (.clk(clk), // input wire clk.probe0(sys_clk), // input wire [0:0]  probe0  .probe1(sin_1mhz), // input wire [7:0]  probe1 .probe2(sin_10mhz), // input wire [7:0]  probe2 .probe3(sin_50mhz), // input wire [7:0]  probe3 .probe4(sin_add), // input wire [9:0]  probe4 .probe5(fir_out) // input wire [31:0]  probe5
);endmodule

2.dds模块

`timescale 1ns / 1psmodule dds_adder3(
input	clk,
output  [7:0] sin_1mhz,
output  [7:0] sin_10mhz,
output  [7:0] sin_50mhz,
output	reg[9:0]	sin_add);//wire	data_tvalid;
//wire[7:0] sin_1mhz;
//wire[7:0] sin_10mhz;
//wire[7:0] sin_50mhz;dds_1mhz u_dds_1mhz (.aclk(clk),                              // input wire aclk//.m_axis_data_tvalid(data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(sin_1mhz)    // output wire [7 : 0] m_axis_data_tdata
);dds_10mhz u_dds_10mhz (.aclk(clk),                              // input wire aclk//.m_axis_data_tvalid(data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(sin_10mhz)    // output wire [7 : 0] m_axis_data_tdata
);dds_50mhz u_dds_50mhz (.aclk(clk),                              // input wire aclk//.m_axis_data_tvalid(data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(sin_50mhz)    // output wire [7 : 0] m_axis_data_tdata
);always@(posedge clk )beginsin_add = {{2{sin_1mhz[7]}},sin_1mhz} + {{2{sin_10mhz[7]}},sin_10mhz} + {{2{sin_50mhz[7]}},sin_50mhz};endendmodule

3.fir模块

`timescale 1ns / 1psmodule fir_ip(
input	clk,
input	[9:0]	fir_in_10,
output	[31:0]	fir_out);reg	[15:0]	fir_in;wire	s_axis_data_tvalid;always @(posedge clk) beginfir_in = {{6{fir_in_10[9]}},fir_in_10};
endassign 	s_axis_data_tvalid = 1'b1;fir_dds_adder3 u_fir_dds_adder3 (.aclk(clk),                              // input wire aclk.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_tdata(fir_in),    // input wire [15 : 0] s_axis_data_tdata//.m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(fir_out)    // output wire [31 : 0] m_axis_data_tdata
);endmodule

代码链接:
工程下载

这篇关于FPGA数字频率合成器及fir滤波器设计(利用vivado dds、fir ip核)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/737840

相关文章

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

java字符串数字补齐位数详解

《java字符串数字补齐位数详解》:本文主要介绍java字符串数字补齐位数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java字符串数字补齐位数一、使用String.format()方法二、Apache Commons Lang库方法三、Java 11+的St

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重

Linux配置IP地址的三种实现方式

《Linux配置IP地址的三种实现方式》:本文主要介绍Linux配置IP地址的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录环境RedHat9第一种安装 直接配置网卡文件第二种方式 nmcli(Networkmanager command-line

Linux虚拟机不显示IP地址的解决方法(亲测有效)

《Linux虚拟机不显示IP地址的解决方法(亲测有效)》本文主要介绍了通过VMware新装的Linux系统没有IP地址的解决方法,主要步骤包括:关闭虚拟机、打开VM虚拟网络编辑器、还原VMnet8或修... 目录前言步骤0.问题情况1.关闭虚拟机2.China编程打开VM虚拟网络编辑器3.1 方法一:点击还原VM

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Nginx实现动态封禁IP的步骤指南

《Nginx实现动态封禁IP的步骤指南》在日常的生产环境中,网站可能会遭遇恶意请求、DDoS攻击或其他有害的访问行为,为了应对这些情况,动态封禁IP是一项十分重要的安全策略,本篇博客将介绍如何通过NG... 目录1、简述2、实现方式3、使用 fail2ban 动态封禁3.1 安装 fail2ban3.2 配

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

Java数字转换工具类NumberUtil的使用

《Java数字转换工具类NumberUtil的使用》NumberUtil是一个功能强大的Java工具类,用于处理数字的各种操作,包括数值运算、格式化、随机数生成和数值判断,下面就来介绍一下Number... 目录一、NumberUtil类概述二、主要功能介绍1. 数值运算2. 格式化3. 数值判断4. 随机

查询SQL Server数据库服务器IP地址的多种有效方法

《查询SQLServer数据库服务器IP地址的多种有效方法》作为数据库管理员或开发人员,了解如何查询SQLServer数据库服务器的IP地址是一项重要技能,本文将介绍几种简单而有效的方法,帮助你轻松... 目录使用T-SQL查询方法1:使用系统函数方法2:使用系统视图使用SQL Server Configu