马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
verilog实现线性插值实现正弦波天生器
最近在项目上遇到一个必要在低资源FPGA上实现FFT逻辑的项目,而且要求实现窗函数。对于窗函数来说,莫非是实现正弦波天生器,正弦波天生器可以使用DDS模块,CORDIC模块,大概查找表的方式实现,以下主要讲解ROM核线性插值相结合的波形天生器,用于天生正弦波。
1.线性插值
线性插值是一种数据估值算法,由于其拟合线是一条直线,所以叫做线性插值。即通过必要估值点的左右两个点的权重以及间隔,对估值点的权重进行盘算的一种算法。
(x1,y1)(x1,y1)(x0,y0)(x0,y0)(x,y)(x,y)Text is not SVG - cannot display由于估值拟合线是直线那么,已知(x0,y0)和(x1,y1),以及x到两点的间隔,对y进行盘算。
\[\begin{split}&\frac{y_1-y_0}{x_1-x_0} = \frac{y-y_0}{x-x_0} \\ &y = y_0 + \frac{(y_1-y_0)*(x-x_0)}{x_1-x_0}\end{split}\]
对正弦函数进行估值:
(x1,y1)(x1,y1)(x0,y0)(x0,y0)(x,y)(x,y)(x2,y2)(x2,y2)Text is not SVG - cannot display其中(x,y)表示估算值,(x2,y2)表示真实值,误差为y2-y,即当x1-x0越小,估算值越准确。样本点越多越精确。
2.样本天生
以下matlab代码用于天生正弦函数样本值,用于进行数据估算。- clc,clear,close all
- %% 生成 rom 数据
- Width=16;
- Depth=256;
- phi=linspace(0,2*pi,Depth+1);
- phi=phi(1:end-1)';
- cos_sig=cos(phi);
- cos_sig=floor(cos_sig*(2^(Width-1)-1));
- plot(cos_sig)
- %% 生成.coe文件
- filename='.\cos_rom.coe';
- fid = fopen(filename,'w');
- radix = 10;
- fprintf(fid,"memory_initialization_radix=%d;\n",radix); %使用的进制
- fprintf(fid,"memory_initialization_vector=");
- for i=1:size(cos_sig,1)
- fprintf(fid,"\n%d",cos_sig(i));
- end
- fprintf(fid,";");
- fclose(fid);
复制代码 3.verilog实现线性插值
以下将使用参数:样本深度256,相位最大值65536进行讲解。
对某一个点进行线性估值的时候,我们必要知道当前点在样本中对应相应点的邻近点。样本邻近两点相位差65536/256 = 256,假设插值相位位置为phase,则相邻点为floor(phase/256)和floor(phase/256)+1,floor表示向下取整,rom表示查找表数据。
那么
\[\begin{equation}y = y_0 + \frac{(y_1-y_0)*(x-x_0)}{x_1-x_0} = rom(floor(phase/256)) + \frac{(rom(floor(phase/256) + 1)-rom(floor(phase/256)))*(phase-floor(phase/256)*256)}{256}\end{equation}\]
以下为VERILOG代码实现:
[code]`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 2025/03/29 15:47:50// Design Name: // Module Name: cos_gen_pipeline// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module cos_gen_pipeline( input clk , input rst , input valid , input [15:0] phase , //相位,0~65535对应0~2pi) output rdy , output reg [15:0] cos_out ); reg [4:0] valid_d; always @(posedge clk) begin if(rst)begin valid_d 8) ; assign addr2 = (phase>>8)+1 ; assign phase1 = addr1 |