Farrow结构的三阶拉格朗日插值matlab及FPGA实现

这篇具有很好参考价值的文章主要介绍了Farrow结构的三阶拉格朗日插值matlab及FPGA实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说明:本文为学习笔记,错误不可避免,全当交流。

以单频点信号为例,说明三阶拉格朗日插值的实现方法。

实现结构

假设输入序列为:X(n)=[…,x(-1),x(0),x(1),x(2)]

Farrow结构的三阶拉格朗日插值matlab及FPGA实现,matlab,开发语言,fpga开发,笔记

以一个x(1)…x(10)的序列为例,说明x的计算与插值过程。

X的计算如图所示,计算出x按照上述结构即可实现插值。

Farrow结构的三阶拉格朗日插值matlab及FPGA实现,matlab,开发语言,fpga开发,笔记

matlab实现

% farrow结构三阶拉格朗日插值的算法
%  y(k)=((c0*uk+c1)*uk+c2)*uk+c3;
% 其中uk为分数间隔,C为滤波结果,非常适合用fpga实现。
% 可用于任意倍率(插值或抽取)的采样率变换。
 close all; clear all;

fs = 1.5e3;
fc = 1e2;
t = 0:1/fs:1/fc;
x = cos(2*pi*fc*t);
% 系数
v0=[-1/6  1/2   -1/2  1/6];
v1=[1/2   -1    1/2    0 ];
v2=[-1/3  -1/2   1   -1/6];
v3=[0      1     0     0 ];

 
I=3; % 插值因子
D=2; % 抽取因子
step_factor=D/I;% 步进因子
k=1;%由第二个点开始,第一个点相等
lengthx=length(x);
xbuf=zeros(4,1);
ukbuf=zeros(1,round(length(x)*I/D));

yy4_1buf=zeros(1,round(I/D*lengthx+4));
yy4_2buf=zeros(1,round(I/D*lengthx+4));
yy4_3buf=zeros(1,round(I/D*lengthx+4));
yy4_4buf=zeros(1,round(I/D*lengthx+4));

yy3_1buf=zeros(1,round(I/D*lengthx+4));
yy3_2buf=zeros(1,round(I/D*lengthx+4));
yy3_3buf=zeros(1,round(I/D*lengthx+4));
pha=0;
x=[x 0 0];%补充0
for i=1:1:length(x)  %输入序列
    %--序列移位
    xbuf(4)=xbuf(3);
    xbuf(3)=xbuf(2);
    xbuf(2)=xbuf(1);
    xbuf(1)=x(i);
    
    %--滤波
    c0=xbuf(1)*v0(1)+xbuf(2)*v0(2)+xbuf(3)*v0(3)+xbuf(4)*v0(4);
    c1=xbuf(1)*v1(1)+xbuf(2)*v1(2)+xbuf(3)*v1(3)+xbuf(4)*v1(4);
    c2=xbuf(1)*v2(1)+xbuf(2)*v2(2)+xbuf(3)*v2(3)+xbuf(4)*v2(4);
    c3=xbuf(1)*v3(1)+xbuf(2)*v3(2)+xbuf(3)*v3(3)+xbuf(4)*v3(4);
    %起始点重合
    if(i==2)   
        y(1)=x(1);
    end
    %进去两个数据后开始插值第一个点
    if(i>2)
    pha = pha + 1;
    while pha >= step_factor
            
            pha = pha - step_factor; % 更新输出采样点后的相位
            uk =pha ;
        ukbuf(k)=uk;

        yy4_1=(c0*uk);%1
        yy4_1buf(k)=yy4_1;
        yy4_2=(yy4_1);
        yy4_2buf(k)=yy4_2;
        yy4_3=(yy4_2+c1);%2
        yy4_3buf(k)=yy4_3;
        yy4_4=(yy4_3);
        yy4_4buf(k)=yy4_4;
        yy4=yy4_4;
        

        yy3_1=(yy4*uk);%3
        yy3_1buf(k)=yy3_1;
        yy3_2=(yy3_1);
        yy3_2buf(k)=yy3_2;
        yy3_3=(yy3_2+c2);%4
        yy3_3buf(k)=yy3_3;
        yy3_4=(yy3_3);
        yy3=yy3_4;
        
        yy2=((yy3*uk+c3));%5
        k = k + 1; % 更新输出索引
        y(k)=yy2;
        m=y(k);
        
        
    end
    end
end


y=y(1:k-1);
t1=(0:length(y)-1)/(fs*I/D);
t = 0:1/fs:(1/fs)*17;
plot(t,x,'--*',t1,y,'--o');


figure(2);
subplot(211);%(x=行,列,计数)
NFFT=length(x);
FS=48*10^3;
signal_I_window =x'.*hamming(NFFT);
signal_I_window_FFT = fft(signal_I_window,NFFT)/NFFT;
plot((-0.5:1/NFFT:0.5-1/NFFT)*(FS),20*log10(fftshift(abs(signal_I_window_FFT(1:NFFT)))));
title('ContData  ');

subplot(212);%(x=行,列,计数)
NFFT=length(y);
FS=48*10^3*I/D;
signal_I_window =y'.*hamming(NFFT);
signal_I_window_FFT = fft(signal_I_window,NFFT)/NFFT;
plot((-0.5:1/NFFT:0.5-1/NFFT)*(FS),20*log10(fftshift(abs(signal_I_window_FFT(1:NFFT)))));
title('ContData  ');

执行结果

Farrow结构的三阶拉格朗日插值matlab及FPGA实现,matlab,开发语言,fpga开发,笔记

FPGA实现

实现结构与matlab相同,fir_core实现滤波器,mult_parallel实现uk的乘加。

Farrow结构的三阶拉格朗日插值matlab及FPGA实现,matlab,开发语言,fpga开发,笔记

C0滤波器的实现

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2023/06/25 08:45:58

// Design Name:

// Module Name: fir4_core

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//


 

module fir4_core#(

parameter                   WIDTH   = 16

)(

input i_sys_clk,

input i_reset_h,

input       [2*WIDTH-1:0]   din,//sfix16_en13  IQ·

output      [2*WIDTH-1:0]   dout


 

    );

   


 

wire        [15:0]              Fn_mem      [3 : 0];//sfix16_14

// assign       Fn_mem[0]           =   16'H1555;

// assign       Fn_mem[1]           =   16'HC000;

// assign       Fn_mem[2]           =   16'H4000;

// assign       Fn_mem[3]           =   16'HEAAB;

assign      Fn_mem[0]           =   16'HEAAB;

assign      Fn_mem[1]           =   16'H4000;

assign      Fn_mem[2]           =   16'HC000;

assign      Fn_mem[3]           =   16'H1555;

reg signed      [2*WIDTH-1:0]       Xn_mem          [3 : 0];

wire    signed      [31:0]              Mult_i_mem      [3 : 0];//sfix32_en27

wire    signed      [31:0]              Mult_q_mem      [3 : 0];//sfix16_en13 MULTI sfix16_en14

wire    signed  [33:0]          Sumi_mem1           ; //sfix34_en27


 

wire    signed  [33:0]          Sumq_mem1           ;

// assign       Xn_mem[0]           =   i_reset_h ? 32'd0 : din;

// genvar   n;

// generate

    // for (n=0; n < 6; n=n+1)begin: delayN

        // shift_ram_N

            // inst1_shift_ram_N(

            // .A                   (0          ),

            // .D                   ({Xn_mem[2],Xn_mem[1],Xn_mem[0]}),

            // .SCLR                (i_reset_h          ),

            // .CLK                (i_sys_clk            ),

            // .Q                   ({Xn_mem[3],Xn_mem[2],Xn_mem[1]})

            // );

always @(posedge i_sys_clk) begin

if(i_reset_h)begin

    Xn_mem[0] <= 0 ;

    Xn_mem[1] <= 0 ;

    Xn_mem[2] <= 0 ;

    Xn_mem[3] <= 0 ;

end

else begin

    Xn_mem[0] <= din;

    Xn_mem[1] <= Xn_mem[0] ;

    Xn_mem[2] <= Xn_mem[1] ;

    Xn_mem[3] <= Xn_mem[2] ;

end


 

end

    // end

// endgenerate

genvar  n1;

generate

    for (n1=0; n1 <= 3; n1=n1+1)begin: mult_gen

        mult_gen_16_16

            insti_mult_gen_16_16(

            .CLK                (i_sys_clk            ),

            .A                  (Xn_mem[n1][15:0]), //(15 DOWNTO 0)                                                                                                        

            .B                  (Fn_mem[n1]     ),  //(15 DOWNTO 0)                                                                                                        

            .P                  (Mult_i_mem[n1] )   //(31 DOWNTO 0)                                                                                                        

            );

        mult_gen_16_16

            instq_mult_gen_16_16(

            .CLK                (i_sys_clk            ),

            .A                  (Xn_mem[n1][31:16]),//(15 DOWNTO 0)                                                                                                        

            .B                  (Fn_mem[n1]     ),  //(15 DOWNTO 0)                                                                                                        

            .P                  (Mult_q_mem[n1] )   //(31 DOWNTO 0)                                                                                                        

            );

    end

endgenerate

wire    j1;

assign   j1=0;

        Sum_4Data#(

            .WIDTH              (32                 )

            )

            insti_Sum_4Data(

            .clk                (i_sys_clk                  ),

            .rst                (i_reset_h                  ),

            .din_1              (Mult_i_mem[0]  ),//32bit

            .din_2              (Mult_i_mem[0+1]    ),

            .din_3              (Mult_i_mem[0+2]    ),

            .din_4              (Mult_i_mem[0+3]    ),

            .dout               (Sumi_mem1      ) //34bit

        );

        Sum_4Data#(

            .WIDTH              (32                 )

            )

            instq_Sum_4Data(

            .clk                (i_sys_clk                  ),

            .rst                (i_reset_h                  ),

            .din_1              (Mult_q_mem[0]  ),//32bit

            .din_2              (Mult_q_mem[0+1]    ),

            .din_3              (Mult_q_mem[0+2]    ),

            .din_4              (Mult_q_mem[0+3]    ),

            .dout               (Sumq_mem1      ) //34bit

        );

       

assign      dout[15:0]          =   Sumi_mem1[30 :15];  //sfix16_en13

assign      dout[31:16]         =   Sumq_mem1[30: 15];  

endmodule文章来源地址https://www.toymoban.com/news/detail-819750.html

mult_parallel模块的实现

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2023/06/26 15:17:47

// Design Name:

// Module Name: mult_parallel

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//


 

module mult_parallel(

input i_sys_clk,

input i_reset_h,

input signed [15:0]  i_fir_c0,

input signed [15:0]  i_fir_c1,

input signed [15:0]  i_fir_c2,

input signed [15:0]  i_fir_c3,

input signed [15:0]  i_uk    ,

output signed [15:0] o_mult_parallel,

output               o_uk_valid      

    );

wire signed [31 : 0] w_mult_P_c0;

wire signed [15 : 0] w_mult_P16_c0;

wire signed [31 : 0] w_mult_P_c1;

wire signed [15 : 0] w_mult_P16_c1;

wire signed [31 : 0] w_mult_P_c2;

wire signed [15 : 0] w_mult_P16_c2;

wire signed [16 : 0] r_add_y1;

wire signed [16 : 0] r_add_y2;

wire signed [16 : 0] r_add_y3;


 

wire signed [15:0]  r_fir_c1_d4;

wire signed [15:0]  r_fir_c2_d9;

wire signed [15:0]  r_fir_c3_d14;

wire signed [15:0]  r_uk_d5;

wire signed [15:0]  r_uk_d10;

assign    w_mult_P16_c0 = w_mult_P_c0[29:14];

assign    w_mult_P16_c1 = w_mult_P_c1[29:14];

assign    w_mult_P16_c2 = w_mult_P_c2[29:14];

c_shift_ram_0 c_shift_ram_c0_inst (

  .A   (  6'd2              ),      // input wire [5 : 0] A

  .D   (  i_fir_c1       ),      // input wire [15 : 0] D

  .CLK (  i_sys_clk    ),      // input wire CLK

  .CE  (  1'b1 ),    // input wire CE

  .Q   (  r_fir_c1_d4  )       // output wire [15 : 0] Q

);

c_shift_ram_0 c_shift_ram_uk_c0_inst (

  .A   (  6'd3              ),      // input wire [5 : 0] A

  .D   (  i_uk       ),      // input wire [15 : 0] D

  .CLK (  i_sys_clk    ),      // input wire CLK

  .CE  (  1'b1 ),    // input wire CE

  .Q   (  r_uk_d5  )       // output wire [15 : 0] Q

);

c_shift_ram_0 c_shift_ram_c1_inst (

  .A   (  6'd7              ),      // input wire [5 : 0] A

  .D   (  i_fir_c2       ),      // input wire [15 : 0] D

  .CLK (  i_sys_clk    ),      // input wire CLK

  .CE  (  1'b1 ),    // input wire CE

  .Q   (  r_fir_c2_d9  )       // output wire [15 : 0] Q

);

c_shift_ram_0 c_shift_ram_uk_c1_inst (

  .A   (  6'd8              ),      // input wire [5 : 0] A

  .D   (  i_uk       ),      // input wire [15 : 0] D

  .CLK (  i_sys_clk    ),      // input wire CLK

  .CE  (  1'b1 ),    // input wire CE

  .Q   (  r_uk_d10  )       // output wire [15 : 0] Q

);

c_shift_ram_0 c_shift_ram_c2_inst (

  .A   (  6'd12              ),      // input wire [5 : 0] A

  .D   (  i_fir_c3       ),      // input wire [15 : 0] D

  .CLK (  i_sys_clk    ),      // input wire CLK

  .CE  (  1'b1 ),    // input wire CE

  .Q   (  r_fir_c3_d14  )       // output wire [15 : 0] Q

);

// always @(posedge i_sys_clk)

// begin

    // r_fir_c1_d1 <= i_fir_c1   ;

    // r_fir_c1_d2 <= r_fir_c1_d1;

        // r_fir_c1_d3 <= r_fir_c1_d2;

        // r_fir_c1_d4 <= r_fir_c1_d3;

                 

// end

//-----------c0

mult_gen_16_16 mult_gen_c0_inst (

  .CLK(  i_sys_clk      ),  // input wire CLK

  .A  (  i_uk           ),      // input wire [15 : 0] A

  .B  (  i_fir_c0       ),      // input wire [15 : 0] B

  .P  (  w_mult_P_c0    )      // output wire [31 : 0] P

);

c_addsub_16_16 c_addsub_16_16_c0 (

  .A    (  w_mult_P_c0[29:14]    ),      // input wire [15 : 0] A

  .B    (  r_fir_c1_d4    ),      // input wire [15 : 0] B

  .CLK  (  i_sys_clk   ),  // input wire CLK

  .CE   (  1'b1        ),    // input wire CE

  .S    (  r_add_y1    )      // output wire [16 : 0] S

);

//----------c1

mult_gen_16_16 mult_gen_c1_inst (

  .CLK(  i_sys_clk           ),  // input wire CLK

  .A  (  r_uk_d5         ),      // input wire [15 : 0] A

  .B  (  r_add_y1[15:0]      ),      // input wire [15 : 0] B

  .P  (  w_mult_P_c1         )      // output wire [31 : 0] P

);

c_addsub_16_16 c_addsub_16_16_c1 (

  .A    (  w_mult_P_c1[29:14]        ),      // input wire [15 : 0] A

  .B    (  r_fir_c2_d9   ),      // input wire [15 : 0] B

  .CLK  (  i_sys_clk   ),  // input wire CLK

  .CE   (  1'b1        ),    // input wire CE

  .S    (  r_add_y2    )      // output wire [16 : 0] S

);

mult_gen_16_16 mult_gen_c2_inst (

  .CLK(  i_sys_clk  ),  // input wire CLK

  .A  (  r_uk_d10    ),      // input wire [15 : 0] A

  .B  (  r_add_y2[15:0]    ),      // input wire [15 : 0] B

  .P  (  w_mult_P_c2    )      // output wire [31 : 0] P

);

c_addsub_16_16 c_addsub_16_16_c2 (

  .A    (  w_mult_P_c2[29:14]    ),      // input wire [15 : 0] A

  .B    (  r_fir_c3_d14    ),      // input wire [15 : 0] B

  .CLK  (  i_sys_clk   ),  // input wire CLK

  .CE   (  1'b1        ),    // input wire CE

  .S    (  r_add_y3    )      // output wire [16 : 0] S

);

assign   o_mult_parallel = r_add_y3[16:1];

endmodule

到了这里,关于Farrow结构的三阶拉格朗日插值matlab及FPGA实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Lagrange插值法实验:求拉格朗日插值多项式和对应x的近似值matlab实现(内附代码)

    已知函数表: 求出Lagrange 插值多项式,并计算x=1.2处的y的近似值。 求解多项式: 求解近似值: 请输入横坐标向量X: X=[1, 2, 4, 5] 请输入纵坐标向量Y: Y=[16,12,8,9] 基函数为: q1(x)=(11 x^2)/12 - (19 x)/6 - x^3/12 + 10/3 q2(x)=(29 x)/6 - (5 x^2)/3 + x^3/6 - 10/3 q3(x)=(4 x^2)/3 - (17 x)/6 - x^3/6 + 5/3 q4(x)=

    2024年02月08日
    浏览(35)
  • 牛顿插值法、拉格朗日插值法、三次插值、牛顿插值多项式、拉格朗日插值多项式

    两点式线性插值 调用Matlab库函数 拉格朗日二次插值: 牛顿二次插值 结果分析:通过对比不同插值方法,可以看到在一定范围内(高次会出现龙格现象),插值次数越高,截断误差越小(插值结果越接近于真实函数值);同时,对于相同次数的插值,由于不同的插值方法它们

    2024年02月11日
    浏览(36)
  • 浅谈拉格朗日插值法

    好像FFT要用到,所以就学习一手 版题 其意义在于: 理解一下: 就是把一个足球踢出去,假设球始终在一个平面上飞行,它的轨迹就可以抽象为 (f(x)) (假设这个函数至于时间有关) 现在你有一些照片,所以你可以得到某几个时间点球的位置,想要还原出这个函数 (f(x)) 的

    2023年04月25日
    浏览(28)
  • 解读 拉格朗日插值法python,保你学明白

    什么是插值法 插值法是一种数学方法,用于在已知数据点(离散数据)之间插入数据,以生成连续的函数曲线。 插值法可以用于确定一个未知数据点的值,并简化复杂的数学计算过程。 插值法的应用广泛,如统计学、工程学、科学研究等领域。 拉格朗日插值法的原理 格朗

    2024年02月08日
    浏览(33)
  • PLC拉格朗日插值(SCL、ST计算源代码)

    插值是对函数进行近似的基本方法,这篇博客主要介绍常用的拉格朗日插值法, Lagrange插值法不太清楚的同学,可以看看数值计算和分析类书籍,网上有很多C语言的拉格朗日插值算法,这里我们主要给出在PLC里利用ST,SCL语言完成拉格朗日插值计算。 1、拉格朗日插值FC  插值

    2024年02月14日
    浏览(37)
  • 数值分析:拉格朗日插值法笔记以及C++代码实现

    插值需求的诞生: 如何通过已知数据得到函数的近似解析表达式,从而获得更多的有用数据。 在实际应用中常常需要根据已知的函数点进行数据、模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法“模拟产生”一些

    2024年02月12日
    浏览(26)
  • 【数值分析】拉格朗日插值法与牛顿插值法的C++实现

    设函数 y = f ( x ) displaystylecolor{red}y=f(x) y = f ( x ) 在区间 [ a , b ] displaystylecolor{red}[a,b] [ a , b ] 上有定义,且 a ≤ x 0 x 1 ⋯ x n ≤ b displaystylecolor{red}a ≤x_0x_1dotsx_n ≤b a ≤ x 0 ​ x 1 ​ ⋯ x n ​ ≤ b ,已知在 x 0 … x n displaystylecolor{red}x_0dots x_n x 0 ​ … x n ​ 点处的值分别为

    2024年02月06日
    浏览(34)
  • n个节点互异的拉格朗日插值基函数之和等于一证明

     拉格朗日插值公式   要证明的 ,其左边拉格朗日基函数的的,也就是说方程用来插值的每个离散点都是,那么对于每个点插入点都满足。那么显然,不考虑其他性质,Ln拉格朗日插值公式是一个n-1次多项式,x最高次数是n个插值点的数目减一,但是它经过n个值为1的点,也就

    2024年02月11日
    浏览(29)
  • 计算机图形学中的曲线问题——拉格朗日插值曲线绘制实践

    限于篇幅,我们将在这篇文章中介绍拉格朗日插值曲线绘制实践,主文章链接: GGN_2015 计算机图形学中的曲线问题 在主文章中我们已经介绍了拉格朗日插值函数的绘制方法。给定一个函数必须通过的点的集合,保证任意两点 x x x 指不同,我们就能构造出一条拉格朗日插值函

    2024年02月14日
    浏览(33)
  • 2、瑞丽-伯纳德对流的拉格朗日拟序结构(FTLE场结果对比)

    在上篇博客中,我简单比较了瑞丽伯纳德对流的FTLE场,但是因为粒子追踪采用的是欧拉方法,所以精度不是很高, 因此与文献中的结果还是有些差别。 下面放一张文献中的FTLE场,参数与上篇文章是一致的,Ra = 1e8;Pr = 1; 本文将详细的介绍如何得到这样的图片,好吧,其实也

    2024年02月09日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包