DSP48E2使用以及FIR滤波器定点设计实现与优化

news/2024/9/18 21:05:13/ 标签: fpga开发

DSP48E2使用以及FIR滤波器定点设计实现与优化

DSP48E2是数字信号处理中最常用的FPGA硬核资源,对于高效率,低消耗实现数字信号处理算法有着极为重要的意义。因此熟练掌握DSP48E2的使用是算法工程化的必备技能。FIR滤波器是因果系统,只有零点没有极点,因此绝对稳定,此外具有线性相位,有限抽头长度,多用于实现低通滤波器、半带滤波器等,是信号处理中最典型的模块。本文由浅入深,通过单个DSP48E2资源实现实数乘法,再到3个DSP48E2实现复数乘法,最后到多个DSP48E2级联实现FIR滤波器,记录了本人在此过程中遇到的问题,与解决办法。含有DSP48E2硬核资源的Xilinx系列的FPGA芯片对实现FIR滤波器进行了专门优化(DSP的级联),因此本人通过FIR滤波器定点设计来掌握DSP48E2的使用,并对对称系数的FIR滤波器进行了结构优化与资源对比。

关键字:DSP48E2,饱和与截位,FIR滤波器,定点设计,优化设计

  1. DSP48E2基础功能

图1 DSP48E2功能框图(ug579)

数字信号处理需使用大量的二进制乘法器和累加器,这些操作可以在专用的DSP内实现,这些DSP属于硬核资源。Xilinx的FPGA器件提供了大量专用的、低功耗DSP slice,并使用DSP48E2原语来定义。7系列FPGA器件中的DSP模块称为DSP48E1,UltraScale架构FPGA器件中的DSP模块则称为DSP48E2,其功能更加强大,对于DSP48E1, DSP48E2的不同,请参阅UG579。

DSP48E2主要包括27位预加器、27*18位二进制补码乘法器、48位ALU单元、SIMD算术单元、模式检测器等部分。能够实现27bit(D端口) +/- 27bit(A端口)的预加27bit(D+/-A),操作方式主要是通过配置INMODE[3:0],其中A端口的输入是30bit,在进入预加器前会截位成27bit,输出也是经过截位的27bit,我们知道27bit + 27 bit 的输出结果至少要28bit才能无误差输出,因此我的理解是预加器最多满足26bit + 26 bit的预加结果无损输出。高于26bit的加法不能在预加器中实现,可以通过DSP48E2的级联来完成。

图2 DSP48E2预加器(ug579)

27*18位二进制补码乘法器主要是实现(D +/- A)*B,B端口的位宽为18bit,配置较为简单INMODE[4],来配置成是打一拍后进行乘法(D + A)*B1,或者是打2拍后进行乘法

(D +/- A)*B2。也就是说INMODE参数主要是控制乘法器的动作,在不使用乘法器的情况下INMODE是无效的。当两个预加结果都输入乘法器时,可实现乘方的功能,需要配置其他参数PREADDINSEL,BMULTSEL。

可通过配置48位的ALU单元实现加法/减法/累加功能,需要OPMODE与ALUMODE。具体的配置过程需要自己查阅ug579,在这里不过多赘述了,OPMODE主要控制输入ALU的信号W,X,Y,Z的选择,ALU控制W,X,Y,Z相加或者做减法。

  1. DSP48E实现乘法与复乘

举个例子,我们要实现两个数相加后乘于另一个数输出运算结果,(D + A2)*B2,那么DSP48E2原语相关的参数该如何配置呢?

A2,B2的意思如前文所述,为A,B 输入的数据,寄存2次后进行运算,为了满足时序要求,我们在使用的过程中尽量要求能用的寄存器都用上,流水线的方式可以优化时序。查阅ug579的table 2-1 、2-3、2-7,我们可以得到3个参数的配置如下。

INMODE = “00100”,OPMODE= “000000101”,ALUMODE=“0000”。具体意义与用法还是建议查阅Xilinx的DSP48E2手册ug579。

    1. 复乘的实现与优化

图3 复数乘法的数学推导

基于复乘的基本理论,我们要实现复数乘法,需要四个乘法器(4个DSP48E2),两个加法器(可通过级联功能实现),如图绿色方框所示;为了节省资源,我们对复乘进行了优化,让其只需要3个乘法即可实现,如红色方框所示,其中第一个与第三个是完全一致的。

       前面我们基于DSP48E2,实现了两个实数的乘法。接下来我们要实现两个DSP48E2的级联,复乘结果的实部,虚部操作一样,因此我们以实部讨论为例。DSP48E2的级联,包括输入信号的级联ACIN,ACOUT,BCIN,BCOUT和输出信号的级联PCIN,PCOUT,Xilinx的DSP48E2资源,对于级联做了专门优化,通过这些端口级联的信号,不占用额外的逻辑资源。如图所示以u2_dsp为例:u0_p(C)-ad_im_2d*(b_re_2d+b_in_2d)

其中u0_dsp的输出结果通过PCIN端口,输入到u2_dsp(或者u3_dsp),并配置OPMODE为“000010101”,ad_im_2d的原因主要是时钟对齐,我们设置了u0_dsp为(A1+ D)*B1,u2_dsp则是设置了(A2+ D)*B2,计算预加与乘法的时间u2多需要一拍,而且 u0_dsp输出需要一拍寄存才能到达u2_dsp(u3_dsp)的PCIN端口,因此为了保证信号同步,u2_dsp,u3_dsp需要延迟2拍输入。

为了更好的理解,我们忽略预加与乘法的时间,保证3个DSP的预加与乘法时间相同(即打拍相同,比如同为(A2+D)*B2),则只要预留u0_dsp的输出P打一拍时间即可,此时,ad_im_1d,b_re_1d,b_im_1d,延迟一拍。

    1. 饱和与截断的处理

1、饱和运算尽量使用DSP模块中的PATTERNDETECT和PATTERNBDETECT端口来实现,而不是使用额外的逻辑资源。

2、使用DSP时可以灵活运用OPMODE来实现抽取、保持、清零、通道复用等功能,而不是仅仅把它作为一个静态配置来使用。

PATTERNDETECT和PATTERNBDETECT端口在算法类设计中这两个端口有一个很有用的功能,就是用来做饱和。如图4所示,PATTERNDETECT和PATTERNBDETECT是一个比较器的输出,这个比较器的作用是把DSP输出端的任意bit和一个数的对应bit做比较,如果相等则PATTERNDETECT为1,如果按位相反则PATTERNBDETECT为1。这个用于比较的数可以是参数设定的固定数,也可以是C端口的输入数据,而bit选择也可以通过参数或C端口进行。

图4 pattern端口

在用于饱和操作时,通常用参数设定固定的比较数和需要比较的bit位,我们知道DSP输出为48位,假如需要对高11bit做饱和操作,输出37bit,则对DSP做如下设置:

.MASK                (48'h000fffffffff         ),// 比较高12bit,低36bit不比较

.PATTERN          (48'h000000000000       ),// 固定比较数为全0

.SEL_MASK                 ("MASK"               ),// 比较bit选择使用“MASK”参数的设定

.SEL_PATTERN  ("PATTERN"           ),// 比较数选择使用“PATTERN” 参数的设定

饱和操作的原理是把DSP输出的符号位部分和12’h0做比较,当输出为正数时,符号位应该等于12’h0,则PATTERNDETECT输出1,当输出为负数时,符号位应该等于12’hfff,即12’h0的按位取反,则PATTERNBDETECT输出1,也就是说如果PATTERNDETECT和PATTERNBDETECT都为0,则表示输出数据溢出了。用如下代码实现最终的饱和输出:

always @ (posedge clk)

begin

    if (PATTERNDETECT || PATTERNBDETECT) begin

        out <= P[36:0];

    end

    else begin

        out <= {P[47],{36{~P[47]}}};

    end

end

当然这只是管中窥豹,DSP48E2的参数加in/out端口数目多达上百个,但是大部分参数都有详细的描述,用一遍就能理解其用法,需要详细领悟的参数/接口不到20个,这些端口需要反复使用才能完全灵活的配置达到自己所需要的功能。我的经验是实践出真知,多试试配置几遍,然后分析错误,就能很快掌握其基本用法。

  1. FIR滤波器的设计与实现

    1. FIR滤波器的定点设计

Matlab是一个非常好用的工具,本文的FIR滤波器设计与数据输出都是基于该工具。利用脚本生成正弦信号和FilterDesigner工具设计一个滤波器,得到浮点信号和浮点滤波器系数,我们需要进行定点化生成2进制或者16进制数据写入txt文档,方便后续Verilog代码读取($readmemb,$reammemh)。下面的代码有两种方式生成16进制或者2进制数据,写入数据的前提都是用round、floor等函数将浮点小数生成整数(round*(2^(N-1)))。

下面的代码是将整形数据写入txt文件,第一种hex file代码简单,且写入迅速,美中不足的是只能写入正数,需要将有符号数转化成无符号数;第二种方法(%注释代码)是以二进制补码写入txt文件,逐bit判断,速度很慢,可以满足写入有符号数的需求,后续将寻找其他函数,来快速写入16进制有符号补码数据。

%%  signed to unsigned and output to txt.file in hex

fid=fopen('C:\... \Desktop\DataIn.txt','w');

unsigned_si = s2us(si,24);

fprintf(fid,"%06x\n",unsigned_si); % fprintf only unsigned hex(%x)number , signed number ?

%%  output  binary complement data  to txt.file

% for k=1:length(si)

%     B_s=dec2bin(si(k)+(si(k)<0)*2^N,N);

%     for j=1:N

%         if B_s(j)=='1'

%             tb=1;

%         else

%             tb=0;

%         end

%         fprintf(fid,'%s',B_s(j));

%     end

%     fprintf(fid,'\r\n');

% end

% fprintf(fid,';');

fclose(fid);

非对称FIR滤波器与DSP48E2实现

我们知道FIR的原理是时域卷积,即

常见的直接型FIR滤波器系统框图如下所示,

图5 直接型FIR滤波器(systolic)

图6 倒置直接型FIR滤波器(transpose)

我们以图5的systolic直接型FIR滤波器的实现为例,实现其功能。

其中x(n)的信号传递可以使用ACIN,ACOUT级联传递,因为只需要延迟一拍,那么ACASCREG ,

AREG均设置为1。

图7 FIR滤波器第一级DSP48E2配置(PREG=0,设置AREG=1,只会有一拍延时)

我们可以从图5发现,当级联的DSP过多时,即FIR阶数太高,最后的加法组合逻辑将非常容易导致系统出现时序问题,时序无法收敛,因此我们在使用的P端口输出,一般会打一拍(PERG =1),充分利用寄存器资源满足我们需要的时序关系。

图8 FIR滤波器第一级DSP48E2配置(AREG=2,PREG=1)

当DSP的输出寄存一拍的时候,我们可以得到FIR滤波器的系统框图如下,在滤波器上下链路都加入一拍寄存器,保证我们得到卷积的结果,(不考虑预加与乘法的延时,设置完全相同,分析时可以忽略),完全利用了DSP48E2的资源,不需要其他逻辑资源完成滤波。需要注意的一点就是级联的打拍数必须 ≤   A 端口的打拍数,即在配置DSP48E2的时候ACASCREG ≤AREG,此时ACASCREG ,AREG均为2, PREG=1。

满足我们所需要的卷积结果。

图9 流水线直接型FIR滤波器

图10 流水线直接型FIR滤波器DSP48级联实现框图

 对称系数FIR滤波器与DSP48E2实现

对于N阶FIR滤波器(N taps),我们需要N个DSP48E2级联来实现,但是我们设计的FIR滤波器大部分都是系数对称的,即h(N-1)=h(0),h(N-2)=h(1)…

FIR滤波器的卷积运算,我们可以得到如下结果,其中N为奇数,保证FIR滤波输出为整数群延时。

因此理论上我们可以利用延时打拍与DSP48E2的预加器,减少一半的乘法资源消耗。

下面是两种具体实现的框图以及前3个DSP的输出结果,同样不考虑加法与乘法的打拍延时(ADREG,MREG)。

图10 对称系数的FIR滤波器实现框图1

同样是满足卷积的结果。仿真也证明该方法的有效性,对于对称结构,节省了一半的乘法资源。

最后一种是完全基于FIR的结构特点,更改了系数与数据流方向,完全做到了不需要任何外部逻辑资源来达到FIR滤波器最优化设计的效果。该结构是目前本人了解到的对称系数的FIR滤波器的最优结构,也是最为推荐的对称系数FIR滤波器的实现结构。

图11 对称系数的FIR滤波器实现框图2(资源最少)

我们同样分析DSP的输出如下,N=15为例,对称系数分别为h(0),h(1),…h(7),总计需要8个DSP48E2,按照数据流分析

仿真实现该结构的过程中尤其要注意就是h的系数反向,与第一个DSP48E2 A端口只需要延时1拍(AREG =1 ,ACASCREG=1,INMODE= “10101”), 其他的DSP48E2的级联端口都是两拍(AREG =2,ACASCREG=2, INMODE= “10100”),设计的关键是保证时序与数据的对齐。出现错误后,可能需要自己一拍一拍的计算,才能定位错误。最后用beyond compare对比数据,切不可仅仅对比前几拍数据,需要大量数据进行比对,才能验证滤波器的功能。


http://www.ppmy.cn/news/1518519.html

相关文章

Spring Boot 项目中,配合 Nacos 、Gateway使用 MinIO

在现代微服务架构中&#xff0c;将不同服务整合并高效地管理配置和流量是至关重要的。Spring Cloud Gateway、Nacos 和 MinIO 是三个关键组件&#xff0c;它们可以一起工作&#xff0c;提供一个灵活、动态和高效的解决方案。下面的方案展示了如何将这三个组件结合起来&#xff…

Nginx: https解决安全问题

https原理 1 &#xff09;http协议存在的问题 数据使用明文传输&#xff0c;可能被黑客窃取 (需要信息加密)报文的完整性无法验证&#xff0c;可能被黑客篡改 (需要完整性校验)无法验证通信双方的身份&#xff0c;可能被黑客伪装 (需要身份认证) 2 ) https 原理 所谓 https,…

【前端面试基础】计算机网络、浏览器、操作系统

计算机网络 一、网络协议与模型 什么是协议&#xff1f; 协议是指计算机系统中完成特定任务所必需的规则和约定&#xff0c;特别是数据传输和交换的规则和约定。OSI和TCP/IP是什么&#xff1f; OSI&#xff08;开放式系统互连参考模型&#xff09;是一种网络架构模型&#xf…

黑神话悟空-妖怪平生录PDF

通关黑神话悟空&#xff0c;并且解锁了两个结局。感触不是那么深&#xff0c;我个人的感觉是剧情上面不如国产单机古剑奇谭三。 与其说黑神话悟空是西游记的延续&#xff0c;不如说是游科CEO对斗战神的执念。 不过&#xff0c;这里面的游记是真的很惊艳&#xff0c;203个妖怪…

Openai api via azure error: NotFoundError: 404 Resource not found

题意&#xff1a;"OpenAI API通过Azure出错&#xff1a;NotFoundError: 404 找不到资源" 问题背景&#xff1a; thanks to the university account my team and I were able to get openai credits through microsoft azure. The problem is that now, trying to us…

Zookeeper官网Java示例代码解读(一)

2024-08-22 1. 基本信息 官网地址&#xff1a; https://zookeeper.apache.org/doc/r3.8.4/javaExample.html 示例设计思路 Conventionally, ZooKeeper applications are broken into two units, one which maintains the connection, and the other which monitors data. I…

c-数据结构(顺序表、链表)

概念 对于n各元素的线性表&#xff0c;严格数学定义&#xff1a;其中任意一个数据元素a[i]&#xff0c;有且仅有一个前驱a[i-1]&#xff0c;有且仅有一个后继a[i1]&#xff1b;首元素a[0]无前驱&#xff0c;尾元素a[n-1]无后继。 顺序表 属于线性表&#xff0c;数据之间的空…

在 Java 中使用泛型时遇到的问题,,无法正确将响应数据映射为需要的数据

public <T> List<T> getOrderList(String shopId, Class<T> tClass) {// --- 省略一些中间过程----ParameterizedTypeReference<KeRuYunCommonResultVO<KPOSPageResultVO<T>>> responseType new ParameterizedTypeReference<KeRuYunCom…

Python日志,按日期分割日志文件(每天一个新的日志文件)

为了创建一个Python类来管理日志&#xff0c;并使其支持按日期分割日志文件&#xff08;每天一个新的日志文件&#xff09;&#xff0c;你可以使用Python标准库中的logging模块和logging.handlers.TimedRotatingFileHandler。下面是一个简单的示例&#xff0c;展示了如何实现这…

linux怎么安装Android Studio

方法一 下载安装包到linux系统解压 tar.gz文件的解压方式为 tar -zxvf 文件名&#xff08;tar -zxvf filename.tar.gz 命令的作用是&#xff0c;使用gzip解压缩&#xff08;-z&#xff09;&#xff0c;解包&#xff08;-x&#xff09;名为filename.tar.gz的归档文件&#xf…

使用PostgreSQL的CLI客户端查询数据不显示问题

问题 今天在使用PostgreSQL的命令行工具&#xff08;CLI&#xff09;查询数据时&#xff0c;数据不显示问题。 解决 使用CLI客户端登录数据库后&#xff0c;需要设置打印&#xff0c;设置边框为2: peterlocalhost testdb> \pset border 2或者&#xff0c;使用元组方式显…

clerk中authenticateWithRedirect方法讲解

clerk.authenticateWithRedirect 主要用于处理 Clerk 的 OAuth 登录过程&#xff0c;其工作流程大致如下&#xff1a; 1、用户发起登录请求&#xff1a; 用户点击登录按钮&#xff0c;触发 OAuth 登录流程。 2、重定向到 OAuth 提供商&#xff1a; clerk.authenticateWithRed…

回溯法-0/1背包问题

什么是回溯法&#xff1f; 回溯法是一种搜索算法&#xff0c;它通过深度优先搜索的方式来解决决策问题。它从根节点开始&#xff0c;逐步扩展节点&#xff0c;直到找到所有可能的解。 回溯法的基本思想 开始节点&#xff1a;从根节点出发&#xff0c;这个节点是解空间的起点…

word文档转html(只支持段落和表格)

maven依赖<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> import org.apache.poi.xwpf.usermodel.*;import java.io.*;public class Wor…

基于Java+SpringMvc+Vue求职招聘系统详细设计实现

基于JavaSpringMvcVue求职招聘系统详细设计实现 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &…

【60天备战软考高级系统架构设计师——第三天:软件工程原则与常用方法】

开篇 软件工程的原则和方法指导开发团队在项目中组织和管理代码及架构。这些原则和方法可以帮助团队提高软件的可维护性和可扩展性。今天&#xff0c;我将重点介绍软件工程中的一些基本原则以及常用方法和工具&#xff0c;帮助大家更好地应对实际开发中的挑战。 软件工程的基…

【Spring Boot 3】【Web】配置HTTPS

【Spring Boot 3】【Web】配置HTTPS 背景介绍开发环境开发步骤及源码工程目录结构背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或多或…

【Android】UIMode

要修改 Android 设备的 UiMode&#xff08;用户界面模式&#xff09;&#xff0c;可以使用 UiModeManager 类进行设置。不同的 UI 模式适用于不同的使用场景&#xff0c;比如夜间模式、汽车模式等。下面是一些常见的修改方法&#xff1a; 1. 修改夜间模式 夜间模式可以通过 U…

Ubuntu/Linux 配置 locale

文章目录 Ubuntu/Linux 配置 locale1 概述2 locale2.1 locale 规则命令规则环境变量优先级 2.2 查看当前 locale 设置2.3 查看当前系统所有可用的 locale2.4 安装中文 locale 语言环境/字符集2.5 安装 locales 包2.6 使用 locale-gen 命令生成语言支持2.7 设置当前默认字符集 3…

基于机器学习的工业制造缺陷分析预测系统

B站视频及代码下载&#xff1a;基于机器学习的工业制造缺陷分析预测系统-视频-代码 1. 项目简介 制造缺陷是工业生产过程中面临的重大挑战之一&#xff0c;对产品质量和生产效率产生直接影响。准确预测和分析制造缺陷的发生&#xff0c;可以帮助企业提高生产质量、降低成本&…