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

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

usaco 1.2 Palindromic Squares(进制转化)

考察进制转化 注意一些细节就可以了 直接上代码: /*ID: who jayLANG: C++TASK: palsquare*/#include<stdio.h>int x[20],xlen,y[20],ylen,B;void change(int n){int m;m=n;xlen=0;while(m){x[++xlen]=m%B;m/=B;}m=n*n;ylen=0;whi

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (