CIC滤波器仿真与实验过程及结果记录
整理于2023-10-08
0.0 前言:
前面介绍了使用matlab中的Filter Designer工具箱进行CIC抽取滤波器设计的仿真过程与结果。下面在前面的基础上针对现有的【正点原子ZYNQ】平台,进行CIC实际设计实验测试。
0.1 平台简介
所使用的演示平台为【正点原子】的领航者ZYNQ开发板以及高速adda模块
1. 实验设计
adc以25MSPS采集一混频(比如:1.25MHz+62.5kHz)信号,经cic抽取滤波后,数据速率降至500kHz,之后由dac输出,通过示波器观察滤波前后波形。
2. matlab 中仿真
步骤:
- 生成待滤波的混频信号信号
- 生成相应的CIC抽取滤波器(见:CIC滤波器设计仿真)
- 进行滤波
- 做图对比
%% 生成信号
Fs = 25e6;
Ts = 1/Fs;
Ts2 = 50/Fs;
T = 1e-2;
N = T*Fs;
N2 = T * (Fs/50);
n = (0:N-1)';
n2 = (0:N2-1)';
t = Ts * n;
t2 = Ts2 * n2;
f = Fs/N*n;
R = 50;
f1 = 1.25e6;
f2 = 50e3;
f3 = 125e3;
s1 = sin(2*pi*f1*t);
s2 = sin(2*pi*f2*t);
s3 = s1 + s2;
% 计算混叠频率
Aliasingf = (1 - (f1/(Fs/R/2) - floor(f1/(Fs/2/50))))*(Fs/R/2)
% 使用cic filtersigner 进行50倍抽取滤波
y3 = H_CIC50(s3); % 信号s3 50倍降采样后得到信号y
y3 = double(y3)/(50^3); % 增益调整,此处未进行补偿滤波器设计
仿真计算结果:

上面两幅图为生成的高采样率混频信号以及其频谱;下面两幅图为滤波后信号及其频谱。可以观察到,经过cic抽取滤波器后,高采样率混频信号得到了显著的降采样和滤波效果,且降采样符合预期;但是波形或者说频谱分布,与预期相差较大,怀疑原因是滤波过程有相位延迟造成的数据点移位而引入的,需要进一步确认。
3. vivado 中仿真
版本:vivado2019.1
3.1 vivado 中 CIC ip核调用
参考来源
xilinx 官方手册:
DS845_cic_compiler
PG140-cic-compiler
IP Catalog 中搜索CIC,打开CIC Compiler,配置cic ip核相关参数。
下图为实现50倍降采样配置。
Filter Options
- Filter Specification
- 滤波器类型 - 抽取
Filter Type : Decimation - 滤波器级数 - 3
Number Of Stages : 3 - 滤波器延迟因子 - 1
Differential Delay : 1 - 通道数 - 1
Number Of Channels : 1
- Sample Rate Change Specification
- 选择固定采样率倍数,设置为 50
另外,还需注意数据位宽设置,根据所需数据特性设置,最终设计结果可以在 Summary 中查看。
左侧可以选择到频响窗口,观察频响特性

生成CIC ip核后,在主程序中例化调用
cic_compiler_0 u_cic_compiler_0 (
.aclk(sys_clk), // input wire aclk
.s_axis_data_tdata(ad_data), // input wire [7 : 0] s_axis_data_tdata
.s_axis_data_tvalid(s_axis_data_tvalid), // input wire s_axis_data_tvalid
.s_axis_data_tready(), // output wire s_axis_data_tready
.m_axis_data_tdata(cic_out_data), // output wire [31 : 0] m_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid) // output wire m_axis_data_tvalid
);
3.2 程序设计
本次实验例程主要参考【正点原子】教程中关于高速adda部分的例程。
程序设计顶层原理图:

3.3 仿真结果
编写testbench文件,调用由matlab生成的波形文件作为仿真输入,观察滤波输出。
3.3.1 matlab生成波形文件
参考来源
基本步骤简述:
- 生成波形(如上所述)
- 按要求位宽做量化处理
- 按16进制写入文件保存
参考程序:
sig2 = s2; % 输入信号
sig2=sig2/max(abs(sig2)); % 归一化处理
sig2=round(sig2*(2^(N-1)-1)); % N比特量化 此处 N = 8
fid=fopen('fitFliterTestData2.txt','w'); % 写入文件保存
data2_i = real(sig2); % 按照指数法生成信号时,提取实部信号
data2_q = imag(sig2); % 按照指数法生成信号时,提取虚部信号
for n=1:length(sig2) % 进行补码替换操作
if data2_i(n) <0
data2_i(n) = 2^N + data2_i(n);
end
if data2_q(n) <0
data2_q(n) = 2^N + data2_q(n);
end
end
fprintf(fid,'%x \n',data2_i); % 按照16进制保存文件
fclose(fid);
3.3.2 vivado 中仿真调用外部数据文件
参考内容
读取文件
$readmemb 和 $readmemh 用来从文件中读取数据到存储器中。其中 readmemb 要求每个数字是二进制数,readmemh 要求每个数字必须是十六进制数字。数字不能包含位宽说明,数字中可以有不定值x或X,高阻值z或Z,和下划线(_),和Verilog语法中的用法是一样的。
一共有下边6种用法:
(1)$readmemb("<数据文件名>",<存储器名>);
(2)$readmemb("<数据文件名>",<存储器名>,<起始地址>);
(3)$readmemb("<数据文件名>",<存储器名>,<起始地址>,<终止地址>);
(4)$readmemh("<数据文件名>",<存储器名>);
(5)$readmemh("<数据文件名>",<存储器名>,<起始地址>);
(6)$readmemh("<数据文件名>",<存储器名>,<起始地址>,<终止地址>);
写入文件
写入文件的操作与C语言类似,首先打开文件,写入数据之后关闭文件。
outputfile = $fopen("file2.txt","w"); 打开文件
$fwrite(outputfile,"%b\n",memory); 写入数据
$fclose(outputfile); 关闭文件
注意:
在写入数据的时候,写入的数据不能是一个数组,必须是单个的数字,因此想写入数组的时候必须要循环单个写入数据,写入数据的数据格式可以是2进制10进制16进制,方式与C语言类似,%控制写入的类型。
代码参考:
//** 数据来源:MATLAB
//** 函数:$readmemh 【以读取16进制形式读取TXT文件】
localparam DATA_NUM = 25000; // 数据量, 也就是txt文件的行数, 如果此参数大于数据行数, 读取到的内容为不定态
reg [7:0] memory[0:DATA_NUM-1] ;//申请250000个8位的存储单元
reg [4:0] n;
initial
begin
$readmemh("../../../../fitFliterTestData3.txt",memory); //fitFliterTestData2.txt中的数字到memory
for(n=0;n<=15;n=n+1) //把15个存储单元的数字打印到 Tcl Console
$display("%h",memory[n]);
// outputfile = $fopen("file2.txt","w");
// for(n=0;n<=7;n=n+1)
// $fwrite(outputfile,"%b\n",filter_out[n]);
// $fclose(outputfile);
end
//<<-- 导入数据 ---------------------------------------------------
//>>-- 传递数据至输入 控制仿真结束 ---------------------
//** 传递数据
//** 数据传递结束 10 个时钟周期后 停止仿真
reg[$clog2(DATA_NUM)-1:0] i=0;
initial
begin
ad_data = 8'd0;
#(clk_period * 10)
for (i = 0; i < DATA_NUM; i=i+1) begin
ad_data = memory[i][7:0];
#(clk_period*2);
end
#(clk_period * 10) $stop;
end
//<<-- 传递数据至 fir_filter 输入 控制仿真结束 -------------------
仿真结果
图中 sys_clk 为系统时钟,50MHz;sys_rst_n 为系统复位信号;ad_data 为输入信号; da_data 为输出信号。可以看出,经过混频信号经过CIC抽取滤波器后,实现了滤波和降采样。

3.4 下载验证
程序编写完成,经vivado编译综合布局布线,生成比特流文件,连接开发板下载,实验验证。本程序中还例化有一个ila,观察采集信号与滤波后信号。
ila探针结果-00:此结果存在有bug,经CIC滤波器输出数据为补码,但是所使用的dac码值使用原码,需要做一下转换
assign da_din = (cic_to_da[7] == 1'b0) ? (cic_to_da + 8'b0111_1111) : (cic_to_da - 8'b0111_1111) ;

修正后的ila结果,可以看出数据正常,并且符合预期。

示波器观察对比:黄色为输入信号,绿色为输出信号。可以看出,此程序实现了滤波和降采样操作。

4. 问题
- 如同在matlab仿真小节中看到的结果一样,经过CIC抽取滤波器后的数据出现了预期之外的谐波峰,后面需要讨论;

- 在进行单频信号做输入时,低频(低于50kHz)信号严重失真;高频(接近截至频率fc=250kHz)信号幅度衰减严重

- 叠加有高频信号时,上述现象会消失,尤其是低频段的现象

上述两种原因怀疑是因为数据长度选择不恰当和滤波器带宽内增益变化大引起,后面需要讨论验证。
CIC滤波器仿真与实验过程及结果记录的更多相关文章
- CIC滤波器
CIC滤波器是滑动平均滤波器的非常高效的迭代实现,只需要一个减法和一个加法,而滑动平均需要N-1个加法. cic滤波器相当于一个梳状滤波器y(n)=x(n)-x(n-D),H(z)=1-z-D,和一个 ...
- Audrion小车实验过程
Audrion小车实验过程 一.实验过程 拷贝光盘文件,安装驱动及Arduino软件,观看了教学视频,明白了软件操作界面的各类按钮的含义,进行了事例的上传实验. 接下来就进行了小车的安装工作,这部分不 ...
- Kettle 实现mysql数据库不同表之间数据同步——实验过程
下面是试验的主要步骤: 在上一篇文章中LZ已经介绍了,实验的环境和实验目的. 在本篇文章中主要介绍侧重于对Kettle ETL的相应使用方法, 在这里LZ需要说明一下,LZ成为了避免涉及索引和表连接等 ...
- VS项目属性配置实验过程
(原创,转载注明出处:http://www.cnblogs.com/binxindoudou/p/4017975.html ) 一.实验背景 cocos2d-x已经发展的相对完善了,从项目的创建.编译 ...
- S3C6410裸奔之旅——RVDS2.2编译、仿真、调试过程 LED流水灯---转的
S3C6410裸奔之旅——RVDS2.2编译.仿真.调试过程 LED流水灯 (2012-10-13 23:56:30) 转载▼ 标签: s3c6410裸奔 ok6410 rvds2.2 rvds2.2 ...
- Mysql: pt-table-checksum 和 pt-table-sync 检查主从一致性,实验过程
一.安装 percona 包 1.安装仓库的包 https://www.percona.com/doc/percona-repo-config/yum-repo.html sudo yum insta ...
- linux中LVM介绍及实验过程
LVM LVM这个词不仅一次出现过,在安装Centos时,磁盘分区时,默认分区就是使用LVM方式分区:再一个就是在OpenStack部署时候用到LVM作为后端存储.对LVM的理解还是不太清晰,查询资料 ...
- 搭建一套简单的web服务器,记录实验过程
搭建web服务器 一.实验内容: 实验要求: 1.完成一个简单的web服务器,web服务器从mysql里读取数据进行返回 2.Mysql需要有一个单独的数据盘,每个mysql虚拟机的磁盘挂载方式需要都 ...
- lab_1 清华大学ucore bootload启动ucore os(预备基础知识+实验过程)
实验1 :bootload启动ucore os 1.0实验内容: lab1中包含一个bootloader和一个OS.这个bootloader可以切换到X86保护模式,能够读磁盘并加载ELF执行文件格式 ...
- Vertica集群扩容实验过程记录
需求: 将3个节点的Vertica集群扩容,额外增加3个节点,即扩展到6个节点的Vertica集群. 实验环境: RHEL 6.5 + Vertica 7.2.2-2 步骤: 1.三节点Vertica ...
随机推荐
- CKS 考试题整理 (13)-使用 sysdig 检查容器里里的异常进程
Task 使用运行时检测工具来检测 Pod tomcat 单个容器中频发生成和执行的异常进程 有两种工具可供使用: sysdig falco 注: 这些工具只预装在cluster的工作节点,不在 ma ...
- 洛谷 P4859 已经没有什么好害怕的了
题目描述 学姐 4 了. 有 \(n\) 个糖果和 \(n\) 个药片,它们要进行一一配对.每个糖果或药片都具有互不相同的能量值,要求配对后,糖果比药片能量高的对数,比剩下的对数恰好多 \(k\),求 ...
- 反转链表 Java版 图文并茂思路分析带答案(力扣第206题)
反转链表 力扣第206题 我们不只是简单的学习(背诵)一个数据结构,而是要分析他的思路,以及为什么要有不同的指针等等 非递归方式: 思路分析:首先要链表有个头指针没有任何问题 然后,我们要将1的下一个 ...
- Linux下日志管理工具Logrotate
背景: 项目上的Nginx和Tomcat已经跑了大半年了,Nginx的access.log和error.log将近1G大小:Tomcat下的catalina.out日志经常跑到打不出日志然后进行手动移 ...
- MODBUS RTU转 EtherNet/IP 网关连接森兰变频器与欧姆龙系统通讯
捷米特JM-EIP-RTU(Modbus转Ethernet/Ip)网关,用于将多个 MODBUS 从站设备接入 ETHERNET/IP 主站网络,实现 MODBUS 转 ETHERNET/IP 功 ...
- 给程序员准备的“蜜糍”--SOD框架简介
注:本文是SOD框架源码仓库的首页介绍,原文地址 一.框架介绍 1,SOD框架是什么? 以前有一个著名的国产化妆品"大宝SOD密",SOD框架虽然跟它没有什么关系,但是名字的确受到 ...
- 【阅读笔记】低照度图像增强-《An Integrated Neighborhood Dependent...
本文介绍的是一种比较实用的低照度图像增强算法,选自2004年Tao的一篇论文,名称是<An Integrated Neighborhood Dependent Approach for Nonl ...
- stegsolve与zsteg的使用
zsteg 介绍:用来检测PNG和BMP中隐藏数据的工具,可以快速提取隐藏信息 使用环境:kali kali自带zsteg,可以用这个指令使用 gem install zsteg 下载完之后查看使用方 ...
- Pandas:在DataFrame中添加一行,并设置行索引
解决方案 效果图 参考链接 https://blog.csdn.net/Caiqiudan/article/details/107788525
- ApiPost: Error:ESOCKETTIMEDOUT
原因 apipost设置响应时间过短 解决方案