FPGA实现CIC抽取滤波器

FPGA实现CIC抽取滤波器

一、什么是CIC滤波器

(一)CIC滤波器原理和结构

CIC(级联积分梳状)滤波器,它是一种高效的多速率信号处理滤波器,是一种无乘法器的线性相位FIR滤波器。常用于数字下变频(DDC)和数字上变频(DUC)中。CIC滤波器的主要优点是不需要乘法器,结构简单,仅由加法器、减法器和寄存器组成。CIC滤波器是FIR滤波器的一种,可以只使用积分器和梳状器来实现,没有了FIR的乘法操作,实现非常的简单并且大大节约了资源。
CIC滤波器有三种工作模式:抽取滤波器(最常用)、插值滤波器和单纯滤波器。

  • 抽取滤波器: 数据流由高速输入变为低速输出,主要应用于数字下变频以及降低采样率的系统中。其结构如下图所示:
在这里插入图片描述
  • 单纯滤波器: 数据流速率不变,积分器和梳状器都工作在同一个采样率下,主要应用于移动平均滤波。

插值滤波器: 数据流由低速输入变为高速输出,主要应用于数字上变频以及提升采样率的系统中。其结构如下图所示:

在这里插入图片描述

前面提到CIC滤波器主要由积分器和梳状器组成,积分器状态方程如下:

在这里插入图片描述


梳状器状态方程如下:

在这里插入图片描述


其中N为抽取倍数(抽取因子),什么意思呢?举个例子输入信号采样率为100MHz,如果抽取因子为10,那么降采样之后的信号速率就是100MHz / 10 = 10MHz。也就是说F_out = F_in / 抽取因子。
由于单级CIC的第一旁瓣阻带衰减是固定的13.46dB,无法很好的抑制旁瓣,因此可以通过级联的方式来提升抑制效果,根据实际旁瓣抑制需求可以实现单级、二级、三级、四级、五级、六级等多级CIC。
可以把CIC滤波器想象成一个多层过滤系统:

  • 一级(N=1):像一层纱网,能过滤掉一些大颗粒杂质,但一些小颗粒和细微的杂质还能通过。
  • 二级(N=2):在纱网后面再加一层更密的滤布,过滤效果更好。
  • 五级(N=5):相当于经过了五层不同精度的过滤,最后得到的液体非常纯净。

级数N越高,滤波效果越好,但系统的“阻力”也会相应增加(对应到FPGA就是资源消耗和位宽增长)。在数字下变频等应用中,N=5 或 N=6 是非常常见的选择,它在性能和资源之间取得了很好的平衡。

假设数据以Fs(假设100MHz)的频率输入滤波器,那数据先通过3级的积分滤波器一直进行累加。假如我们希望得到Fs的10分频的采样数据,那就将积分滤波器的最后一级输出以Fs/N(10MHz)的频率进入梳状滤波器,梳状滤波器其实是微分运算,即当前值减去上一次的值。经过3次的梳状滤波器,最后1级的结果即为抽取的数值。

在这里插入图片描述

(二)最大位宽计算

上面提到CIC滤波器中计算存在加减法操作,因此我们需要考虑到计算过程中信号位宽的问题,这是CIC实现中最需要关注的问题。由于积分器的累加效应,内部数据位宽会随着级数N线性增长。

最大位宽计算公式如下:

B_max = B_in + N * ceil(log2(R * M))

ceil()–向上取整函数
  • B_in:输入位宽
  • R:抽取/插值因子
  • M:差分延迟(通常为1)

举个例子:假设 B_in=16位, R=64, M=1, ceil(log2(64)) = 6。

  • 当 N=3 时,最大位宽 = 16 + 3*6 = 34位
  • 当 N=5 时,最大位宽 = 16 + 5*6 = 46位
  • 当 N=6 时,最大位宽 = 16 + 6*6 = 52位

可以看到,级数每增加一级,位宽就会显著增加,消耗更多的寄存器、逻辑和布线资源。
级数N对滤波器性能的影响:
1、阻带抑制(抗混叠/抗镜像性能)
这是增加级数最主要的目的。N越高,阻带衰减越大,滤波器对带外信号的抑制能力就越强。在频谱上看,旁瓣的幅度会显著降低。这对于抽取器来说,意味着能更好地防止混叠;对于插值器来说,意味着能更好地抑制镜像。

2、通带衰减(副作用)
这是增加级数带来的主要代价。N越高,通带内的衰减也越严重。这意味着我们想要的信号,尤其是通带边缘的信号,也会被显著衰减。为了补偿这种通带衰减,通常需要在CIC滤波器后面级联一个补偿FIR滤波器。

二、CIC抽取滤波器FPGA实现

(一)Verilog代码

以下CIC滤波器代码参数:
级数:3
抽取因子:16

`timescale 1ns /1ps //////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 2025/10/13 15:11:49// Design Name: // Module Name: cic_down_sample// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// ////////////////////////////////////////////////////////////////////////////////// module cic_down_sample#( parameter DATA_IN_WIDTH =8, parameter DATA_OUT_WIDTH =8, parameter CIC_FACTORS =16,// 抽取因子 parameter MAX_WIDTH =20// 最大位宽)( input clk , input rstn , input signed[DATA_IN_WIDTH-1:0] data_in , input data_in_valid , output signed[DATA_OUT_WIDTH-1:0] data_out ); wire signed[MAX_WIDTH-1:0] add_data_0 ; wire signed[MAX_WIDTH-1:0] add_data_1 ; wire signed[MAX_WIDTH-1:0] add_data_2 ; reg signed[MAX_WIDTH-1:0] data_0 ; reg signed[MAX_WIDTH-1:0] data_1 ; reg signed[MAX_WIDTH-1:0] data_2 ; reg [4:0] cnt_div ; reg sample_flag ;// 采样标志 reg signed[MAX_WIDTH-1:0] comb_in ; wire signed[MAX_WIDTH-1:0] add_comb_0 ; wire signed[MAX_WIDTH-1:0] add_comb_1 ; wire signed[MAX_WIDTH-1:0] add_comb_2 ; reg signed[MAX_WIDTH-1:0] comb_0 ; reg signed[MAX_WIDTH-1:0] comb_1 ; reg signed[MAX_WIDTH-1:0] comb_2 ;// 积分器 always @(posedge clk or negedge rstn) begin if(!rstn)begin data_0 <= 'd0 ; data_1 <= 'd0 ; data_2 <= 'd0 ; end else begin data_0 <= add_data_0 ; data_1 <= add_data_1 ; data_2 <= add_data_2 ; end end assign add_data_0 ={{12{data_in[7]}},data_in}+ data_0 ; assign add_data_1 = add_data_0 + data_1 ; assign add_data_2 = add_data_1 + data_2 ;// 降采样处理 always @(posedge clk or negedge rstn) begin if(!rstn)begin cnt_div <= 'd0 ; end elseif(cnt_div == CIC_FACTORS -1)begin cnt_div <= 'd0 ; end else begin cnt_div <= cnt_div +1; end end always @(posedge clk or negedge rstn) begin if(!rstn)begin sample_flag <=1'b0 ; end elseif(cnt_div == CIC_FACTORS -1)begin sample_flag <=1'b1 ; end else begin sample_flag <=1'b0 ; end end // 梳状器 always @(posedge clk or negedge rstn) begin if(!rstn)begin comb_in <= 'd0 ; end elseif(sample_flag)begin comb_in <= add_data_2 ; end end always @(posedge clk or negedge rstn) begin if(!rstn)begin comb_0 <= 'd0 ; comb_1 <= 'd0 ; comb_2 <= 'd0 ; end elseif(sample_flag)begin comb_0 <= comb_in ; comb_1 <= add_comb_0 ; comb_2 <= add_comb_1 ; end end assign add_comb_0 = comb_in - comb_0 ; assign add_comb_1 = add_comb_0 - comb_1 ; assign add_comb_2 = add_comb_1 - comb_2 ; assign data_out = add_comb_2[19:12];// endmodule 

顶层文件:

`timescale 1ns /1ps //////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 2025/10/13 15:45:40// Design Name: // Module Name: cic_top// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// ////////////////////////////////////////////////////////////////////////////////// module cic_top( input sysclk , input sysrstn ); wire m_axis_data_tvalid ; wire signed[7:0] m_axis_data_tdata ; wire signed[7:0] data_out ; dds_compiler_0 dds(.aclk( sysclk ),// input wire aclk.m_axis_data_tvalid( m_axis_data_tvalid),// output wire m_axis_data_tvalid.m_axis_data_tdata( m_axis_data_tdata ),// output wire [7 : 0] m_axis_data_tdata.m_axis_phase_tvalid(),// output wire m_axis_phase_tvalid.m_axis_phase_tdata()// output wire [31 : 0] m_axis_phase_tdata); cic_down_sample#(.DATA_IN_WIDTH(8),.DATA_OUT_WIDTH(8),.CIC_FACTORS(16),// 抽取因子.MAX_WIDTH(20)// 最大位宽)u_cic_down_sample(/*input */.clk( sysclk ),/*input */.rstn( sysrstn ),/*input signed [DATA_IN_WIDTH-1:0] */.data_in( m_axis_data_tdata/*{~m_axis_data_tdata[7],m_axis_data_tdata[6:0]}*/),/*input */.data_in_valid( m_axis_data_tvalid ),/*output signed [DATA_OUT_WIDTH-1:0] */.data_out( data_out )); endmodule 

(二)仿真分析

级数:3 抽取因子:16

在这里插入图片描述


级数:3 抽取因子:8

在这里插入图片描述


可以看到抽取因子越小或级数越小时,CIC抽取滤波器输出波形约平滑,因此需要有必要时级联一个补偿FIR滤波器。

Read more

CVPR 2026 Oral实测|YOLO-DRONE:无人机低空巡检的“性能天花板”,小目标召回率狂升39%(清华团队力作,电力部署实操全解析)

CVPR 2026 Oral实测|YOLO-DRONE:无人机低空巡检的“性能天花板”,小目标召回率狂升39%(清华团队力作,电力部署实操全解析)

前言:作为长期深耕无人机计算机视觉落地的算法工程师,我始终认为,无人机低空巡检场景的核心痛点,从来不是“模型精度多高”,而是“能否适配复杂飞行工况下的实战需求”。无论是电力巡检中的导线断股、绝缘子破损,还是安防巡检中的人员遗留、设备异常,这些目标往往尺寸极小、飞行过程中受风速扰动导致画面模糊、目标尺度动态变化,传统YOLO系列模型要么小目标漏检严重,要么抗扰动能力弱,要么实时性不足,根本无法满足工业级巡检的落地要求。 2026年CVPR大会上,清华大学团队提出的YOLO-DRONE模型惊艳全场,成功入选Oral(口头报告),成为低空巡检领域唯一入选的单阶段检测模型。这款专为无人机低空巡检设计的多尺度动态感知模型,创新性融合自适应尺度感知头(ASPH)与风速补偿特征对齐模块,彻底解决了传统模型“小目标漏检、抗扰动差、实时性不足”三大痛点——在UAV-DT无人机巡检专用数据集上,小目标召回率直接提升39%,同时支持1080p@45FPS实时处理,目前已正式部署于国内某省级电力巡检系统,实现输电线路的自动化巡检落地。 我第一时间获取了YOLO-DRONE的技术论文及开源代码,搭建了模拟无

AiOnly大模型深度测评:调用GPT-5 API+RAG知识库,快速构建智能客服机器人

AiOnly大模型深度测评:调用GPT-5 API+RAG知识库,快速构建智能客服机器人

声明:本测试报告系作者基于个人兴趣及使用场景开展的非专业测评,测试过程中所涉及的方法、数据及结论均为个人观点,不代表任何官方立场或行业标准。 引言 AI 技术加速渗透各行各业的今天,你是否也面临这样的困境:想调用 GPT-5、Claude4.5等顶尖模型却被海外注册、跨平台适配搞得焦头烂额?想快速搭建智能客服、内容生成工具,却因模型接口差异、成本不可控而望而却步?或是作为中小团队,既想享受 AI 红利,又受限于技术门槛和预算压力? AiOnly平台的出现,正是为了打破这些壁垒。 本文将从实战角度出发,带你全方位解锁这个「全球顶尖大模型 MaaS 平台」:从 5 分钟完成注册到 API 密钥创建,从单模型调用到融合 RAG 知识库的智能体开发,然后手把手教你在 Windows 环境部署一个日均成本不足 0.5 元的电商客服机器人。无论你是 AI 开发者、企业运营者,还是想低成本尝试 AI

HarmonyOS6 底部导航栏组件 rc_concave_tabbar 使用指南

HarmonyOS6 底部导航栏组件 rc_concave_tabbar 使用指南

文章目录 * 前言 * 组件特性 * 适用场景 * 使用说明 * 安装组件 * 安装步骤 * 步骤一:引入相关依赖 * 步骤二:创建菜单数据 * 步骤三:使用导航组件 * 运行效果 * 参数介绍 * TabsConcaveCircle 组件参数 * TabMenusInterfaceIRequired 菜单项配置 * 进阶使用 * 自定义单个菜单项颜色 * 调整动画速度 * 自定义高度和颜色 * 注意事项 * 总结 前言 rc_concave_tabbar 是一个功能强大、样式精美的 HarmonyOS 底部导航栏组件库,提供凹陷圆形动画效果样式,适用于多种场景。本篇将介绍 rc_concave_tabbar 的使用方法以及其相关的设计理念。 组件特性 * 流畅动画:支持流畅的凹陷圆形切换动画效果 * 高度定制:支持自定义背景色、字体颜色、高度等多种样式配置 * 灵活配置:支持全局配置和单项配置,满足不同场景需求

OpenClaw 接入飞书机器人保姆级教程

OpenClaw 接入飞书机器人保姆级教程

如果你的 OpenClaw 已完成初始部署、WebUI 可正常收发回复,现在想接入飞书机器人,这篇教程会带你从创建机器人到配置完成,一步到位。 相信你在部署 OpenClaw 时已经踩过不少坑,这篇文章会帮你尽量避开飞书对接中的常见问题,少走弯路。废话不多说,教程正式开始!原文地址 内置飞书插件 如果您使用的是最新版本的 OpenClaw那么已经内置了 Feishu 插件,通常不需要让我们单独进行安装。 如果您使用的是之前比较旧的版本,或者是没有内置的 Feishu 的插件,可以手动进行安装,执行下方命令: 创建飞书机器人 我们先来创建飞书的应用,我们可以复制下方地址进行一键直达 创建企业自建应用 打开后,我们点击【创建企业自建应用】,如果您还没有飞书账号的话,请先注册飞书的账号后再进行创建应用 我们创建企业自建应用然后输入应用名称和应用描述,还有应用图标,我们都可以自定义进行上传,或者选择其他照片当作应用图标。输入完之后我们点击创建 获取 AppID 和 AppSecret 我们点击凭证与基础信息一栏查看我们的App ID 和 App