Matlab里面的浮点数与FPGA定点数的相互转化应用(含Matlab代码,封装成函数可直接调用)

本文主要是介绍Matlab里面的浮点数与FPGA定点数的相互转化应用(含Matlab代码,封装成函数可直接调用),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

1.前言

Matlab里面计算通常用的是浮点数,而FPGA在做数字信号处理时,为了节约资源,常常使用的是定点数。在实践中,我们经常需要将Matlab实现中的算法,用FPGA进行实现。

那么,Matlab里面的是浮点数怎么转换为定点数到FPGA里面进行使用,以及FPGA里面计算的定点数,怎么又在Matlab里面又转换为浮点数进行验证呢?

2.模拟信号——>数字信号

模拟信号是需要通过采样、量化、编码才能转化为数字信号进行处理。
image

模拟信号——>数字信号

通常在Matlab里面仿真算法的时候,只是将模拟信号进行了采样,即时间域上做了离散处理,使模拟信号变成数字序列,但是并没有将幅度值进行量化和编码,是不能够直接用于FPGA处理的。

2.1采样过程

采样过程是进行模拟信号数字化的第一步,模拟信号被采样后,称为采样信号,采样信号在时间上是离散的,但在取值上仍然是连续的,因此仍然是模拟信号。在采样时就不得不提及采样定理:

若想能够从采样后信号中恢复出原始信号,则采样信号的频率至少为原始信号最大频率的2倍,该频率又被称为奈奎斯特频率。

在理想情况下可以看作是用一连串的冲激函数与原始信号进行相乘,若要对采样信号求频谱可以先求冲击串的傅里叶级数,再用傅里叶级数来表示其傅里叶变换,即可以较少的计算量求出采样信号的傅里叶变换。

但在matlab中则不常采用这种方式,常采用的方式为,规定好时间间隔和起始时间后,对原始信号的每个规定时间间隔后的点进行取样,即可得到采样函数。

2.2量化

这里只讨论均匀量化:设模拟抽样信号的取值范围在a和b之间,量化电平数为M,则在均匀量化时的量化间隔为:
Δ v = b − a M Δ v =\frac{b-a}{M} Δv=Mba

且量化区间的端点为:
m i = a + i Δ v m i =a+i \Delta v mi=a+iΔv

设对模拟信号的抽样值为: m ( k T s ) m(kTs) m(kTs) 所选均匀量化的量化区间端点为: m 1 , m 2 , m 3 . . . . . . m n m_1,m_2,m_3......m_n m1,m2,m3......mn
,则根据公式:
m q ( k T s ) = q i ,( m i − 1 ⩽ m ( k T s ) ⩽ m i ) m_q\left( kT_s \right) =q_i\text{,(}m_{i-1}\leqslant m\left( kT_s \right) \leqslant m_i\text{)} mq(kTs)=qi,(mi1m(kTs)mi

就把模拟抽样信号 m ( k T s ) m(kTs) m(kTs)变换成了量化后的离散抽样信号,即量化信号。

非均匀量化读者感兴趣可以自行查阅相关资料。

2.3编码

前面的几篇文章中,我们详细讲解了计算机算法中的数字表示法。在使用FPGA进行信号处理时,常采用有符号的二进制补码进行存储计算。

定点数表示法

以 8 位为例,我们约定从高位开始,1位符号位,4位整数位,后3位表示小数部分。

对于数字 -1.5 用定点数表示就是这样:

首先表示数字正的1.5,即原码:
1. 5 ( D ) = 0000110 0 ( B ) 1.5_{(D)} = 00001 100_{(B)} 1.5(D)=00001100(B)
符号位不变,其余各位取反,+1得:
0111001 1 ( B ) + 1 = 0111010 0 ( B ) 01110 011_{(B)} + 1 = 01110 100_{(B)} 01110011(B)+1=01110100(B)
然后对于负数,符号位填充为"1"得数字 -1.5 用定点数表示:
− 1. 5 ( D ) = 1111010 0 ( B ) -1.5_{(D)} = 11110 100_{(B)} 1.5(D)=11110100(B)

表示步骤如下:

1.在有限的 bit 宽度下,先约定小数点的位置,一般取高位为符号位
2.先不管符号,整数部分和小数部分,分别转换为二进制表示
3.对于正数,两部分二进制组合起来,即是结果
4.对于负数,除符号位进行取反,然后+1,符号位填充"1"

3.举例说明

比如前面在进行OFDM调制映射时,复数以8位定点数形式进行输出,格式为:1位符号位,一位整数位,6位小数位,负数以补码形式表示。

16QAM调制的星座图映射如下表:

Input bits (b0 b1)I-outInput bits (b2 b3)Q-out
00–300–3
01–101–1
111111
103103

映射过后,为了使平均功率一致,还需要乘上归一化因子,这就使得调制后的输出是复数形式的小数。

归一化因子

当输入为0 1 1 0时,映射后实部和虚部输出分别是-1,3。进行归一化后为 − 0.3125 + 0.9531 i -0.3125 + 0.9531i 0.3125+0.9531i。编码过后是11000011 + 00111101i。

这一步是怎么做到的呢?在Matlab中我是这样做的,当然也有其他办法,答案不唯一。

3.1 Quantizer函数:按给定间隔将输入离散化

在Matlab中,Quantizer 模块使用量化算法离散化输入信号。该模块使用舍入到最邻近整数方法将信号值映射到由量化区间定义的输出端的量化值。平滑的输入信号在量化后可能会呈现阶梯形状。

可以去看官方文档:https://ww2.mathworks.cn/help/simulink/slref/quantizer.html

以下方程用数学方法说明舍入到最邻近整数方法:

y = q ∗ r o u n d ( u / q ) y = q * round(u/q) y=qround(u/q)
其中,y 是量化输出,u 是输入,q 是量化区间。

在matlab命令行窗口输入:

q= quantizer()

如下图:
image
可以看到量化格式q包含着四个参数‘datamode’,‘roundmode’,‘overflowmode’,‘format’,默认分别是’fixed’,‘floor’,‘saturate’,[16,15]。

quantizer函数的4个输入参数,不限制输入顺序,不限制输入个数。但还是按顺序分别输入好。

四个参数的意思和可选择的模式如下:

1)DataMode数据类型,默认是’fixed’。除默认还有4种。

‘fixed’— 有符号定点模式。

‘ufixed’— 无符号定点模式。

‘float’— 自定义精度浮点模式。

‘single’— 单精度模式。此模式将覆盖所有其他属性设置。

‘double’— 双精度模式。此模式将覆盖所有其他属性设置。

2)RoundMode取整模式,默认是‘floor’。除默认还有5种

‘floor’— 向下舍入到下一个允许的量化值。
‘convergent’— 舍入到最接近的允许量化值。仅当舍入后的最低有效位设置为 0 时,恰好位于两个最接近的允许量化值之间的数字才会向上舍入。

‘fix’— 向上舍入负数,将正数向下舍入到下一个允许的量化值。

‘ceil’— 向上舍入到下一个允许的量化值。

‘nearest’— 舍入到最接近的允许量化值。介于两个最接近的允许量化值之间的数字将向上舍入。

‘round’— 舍入到最接近的允许量化值。介于两个最接近的允许量化值之间的数字将以绝对值向上舍入。

3)OverFlowMode溢出如何处理,默认’saturate’,针对定点类型的参数,如果对浮点型设置了这个参数会没用,不会报错。

‘saturate’— 溢出饱和。

当要量化的数据值位于数据格式属性指定的最大和最小可表示数字的范围之外时,这些值将量化为最大或最小可表示值的值,具体取决于哪个值最接近。

‘wrap’— 溢出换行到可表示值的范围。

更换范围。超出动态范围的浮点数溢出到 ±Inf

4)Format数据的格式,默认[16,15]。

对于fixed和ufixed是【数据全长,小数位长】

例如fixed,设置[8,6],数据全长8,小数位长6,符号位占1位,整数位占1位,所以能表示的数据范围是[-2,1.984375]。对应二进制’10000000’ ‘01111111’。

以上四种参数按需求设置即可。

3.2 num2bin函数:使用 quantizer 对象将数字转换为二进制表示

语法:

y = num2bin(q,x);

说明:

y = num2bin(q,x) 使用 quantizer 对象 q 指定的数据类型属性,将数值数组 x 转换为在 y 中返回的二进制字符向量。

如果 x 是包含数值矩阵的元胞数组,则 y 将是包含二进制字符串的相同维数的元胞数组。如果 x 是结构体,则 x 的每个数值字段都会转换为二进制。

[y1,y2,…] = num2bin(q,x1,x2,…) 将数值矩阵 (x1, x2 …) 转换为二进制字符串 (y1, y2 …)。

更详细的,可以去官网查看:https://ww2.mathworks.cn/help/fixedpoint/ref/num2bin.html

4.Matlab代码

下面是一个16-QAM调制映射,复数以8位定点数形式进行输出,格式为:1位符号位,一位整数位,6位小数位,负数以补码形式表示的Matlab代码。

%function [map_data]=maping(data_in)
data_in = [0 1 1 0];
%16QAM调制,符合802.11a标准
%%data_in为输入数据
%data_outI,data_outQ为映射后的星座数据
% Input bits (b0 b1) I-out Input bits (b2 b3) Q-out
%              00     –3               00     –3
%              01     –1               01     –1
%              11       1               11       1
%              10       3               10       3
Kmod=sqrt(10);%归一化量
L=length(data_in)/4;%I,Q支路输出的长度
%IQ初始化
data_outI=zeros(1,L);
data_outQ=zeros(1,L);
%星座映射
for k=1:Lswitch (data_in(4*k-3))*2+data_in(4*k-2)    %data_outIcase 0      %00data_outI(k)=-3;case 1      %01data_outI(k)=-1;case 3   %11data_outI(k)=1;case 2      %10data_outI(k)=3;otherwiseendswitch (data_in(4*k-1))*2+data_in(4*k)   %data_outQcase 0      %00data_outQ(k)=-3;case 1      %01data_outQ(k)=-1;case 3      %11data_outQ(k)=1;case 2      %10data_outQ(k)=3;otherwiseend
end
%归一化
data_outI=data_outI/Kmod;
data_outQ=data_outQ/Kmod;
map_data = data_outI + data_outQ*1j;
q = quantizer('fixed','round','saturate',[8,6]);
map_data = num2bin(q,map_data);
%map_data = bin2num(q,map_data)';

取消注释第一行,将第二行注释,可以当成函数调用。
微信公众号获取更多FPGA相关源码:
在这里插入图片描述

这篇关于Matlab里面的浮点数与FPGA定点数的相互转化应用(含Matlab代码,封装成函数可直接调用)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.