目录
1. 背景介绍
基于UltraScale+ XCZU 7ev 平台,对任意数据源采样,然后流水线式计算RMS。
软件:Vivado 2021.1
2. RMS
RMS计算方法:先平方、再平均、然后开方。 从时域计算公式中可以看到,RMS与数据点的个数有关。
时域计算公式:
频域计算公式
3. 思路
FPGA中选取过去N个点,然后先平方、再平均、然后开方。 所用IP核:floating-point,floating-point IP可以实现浮点/定点数的加减乘除平方开方等基础运算。
其他途径:multiply adder, adder 等IP,但是数据类型为32/64位整型,中间计算位宽会拓展,需注意的细节较多。
4. 具体实现
4.1 思路1
定义 x(0), x(1), x(2), x(3), ..., x(N), x(N+1), ..., 为依次收到的数据,x(0)最早接收。定义 y=x^2 .
1. 先将数据依次进行数据类型转换(floating_d2f,定点转浮点),然后平方(floating_multiply);
2. 先将 multiply 的输出结果输入FIFO缓存,同时输入 floating_add 做N次累加,累加之和记为 Sigma;
3. 累加N次后,得到了N个数据的平方和。下一步Sigma应该加上第N+1个数据,同时减去第0个数据。则求和模块的两个输入不应再是y和Sigma,变为 y(N+1) - y(0) 和 Sigma,即 Sigma(t+1)= Sigma(t) + y(N+1) - y(0) ;
4. fifo_mult_delay 是深度 > N+1 的FIFO,在 t(N+1) 时刻输出最早的数据 y(0) ;
5. add_delta 模块实现 y(N+1) - y(0) ,其输出在 t(N+1) 时刻后给到 floating_add 的输入。
6. 后续将 Sigma 依次做除法平均、开方、数据类型转换等。
重要备注:
1. 由于各模块计算有延迟,所以数据不能连续使能。实际测试数据几十个 clk 使能一次时OK。使能周期 T_sample 的下限待测。
2. 上述实现思路的说明中,N+1, N 等角标可能有误,可能多加或多减了一个数据,利用常数数据输入仿真下即可精细调试。
3. 核心是 floating_add 模块的输入控制,这部分本应该用状态机来做,实际用cnt来写控制了,待优化。
4. floating_add 等模块的输入输出,用 assign 做控制判断时,出现了很多奇怪的结果,后来逐步调试换成时序逻辑好了,此处有坑,应该是与IP核的内部计算方法及输出类型有关,也需注意。
5. floating-point IP rst 信号为0时,输出不一定为0,数据输入 valid 信号做 rst 控制反而可以实现输出归0.
6. 数据个数N和数据使能周期会共同影响结果的正确性。当N较大时,使能周期也较长时,N * T_sample >> T_data 数据周期时,结果误差较小,但显然延迟会增大。
4.2 思路2
定义 x(0), x(1), x(2), x(3), ..., x(N), x(N+1), ..., 为依次收到的数据,x(0)最早接收。定义 y=x^2 .
1. 先将数据依次进行数据类型转换(floating_d2f,定点转浮点),然后平方(floating_multiply);
2. 先将 multiply 的输出结果输入FIFO缓存,同时输入 floating_add 做N次累加,累加之和记为 Sigma;
3. 累加N次后,得到了N个数据的平方和。下一步Sigma应该加上第N+1个数据,同时减去第0个数据。利用 subtract 减法模块,subtract_out = Sigma - y(0) ;
4. 求和模块的两个输入变为 y(N+1) 和 subtract_out,即 Sigma(t+1)= subtract_out + y(N+1) ;
5. fifo_mult_delay 是深度 > N+1 的FIFO,在 t(N+1) 时刻输出最早的数据 y(0) ;
6. 后续将 Sigma 依次做除法平均、开方、数据类型转换等。
** 这种思路由于模块rst控制等原因没调通,但理论上是可实现的。
5. 仿真
矩形波+sin波做数据输入,设定N=8000,可以看到输出的RMS逐步跟随变化然后稳定。
6. 下板结果
峰值 115 的sin波计算输出 RMS 在 79~82 左右。(截图时间轴不对应)