Verilog编程中数据对齐问题_内插滤波器

在Verilog编程中常常会遇到数据延时问题,进行计算的时候就需要将数据的时序对齐。本文以内值滤波器的实现为例,记录一下编程需要考虑的延时和数据截断问题。
插值滤波器的计算公式为
f 1 = 0.5 x ( m ) − 0.5 x ( m − 1 ) − 0.5 x ( m − 2 ) + 0.5 x ( m − 3 ) f 2 = 1.5 x ( m − 1 ) − 0.5 x ( m ) − 0.5 x ( m − 2 ) − 0.5 x ( m − 3 ) f 3 = x ( m − 2 ) y I ( k ) = f 1 u ( k ) u ( k ) + f 2 u ( k ) + f 3 \begin{aligned} &f_1 = 0.5x(m)-0.5x(m-1)-0.5x(m-2)+0.5x(m-3)\\ &f_2=1.5x(m-1)-0.5x(m)-0.5x(m-2)-0.5x(m-3)\\ &f_3=x(m-2)\\ &y_I(k) = f_1u(k)u(k)+f_2u(k)+f_3 \end{aligned} f1=0.5x(m)0.5x(m1)0.5x(m2)+0.5x(m3)f2=1.5x(m1)0.5x(m)0.5x(m2)0.5x(m3)f3=x(m2)yI(k)=f1u(k)u(k)+f2u(k)+f3
模块的输入输出端口定义,及输入数据移位缓存。定义4个reg变量用于存储输入数据。

module InterpolateFilter(
  input rst_n,
  input clk,
  input signed[15:0] din,
  input signed[15:0] uk,
  output signed[17:0] dout
);
//输入数据缓存
reg signed[15:0] din_1, din_2, din_3, din_4;
always@(posedge clk or negedge rst_n) begin
  if(!rst_n) begin
    din_1 <= 16'd0;
    din_2 <= 16'd0;
    din_3 <= 16'd0;
    din_4 <= 16'd0;
  end
  else begin
    din_1 <= din;
    din_2 <= din_1;
    din_3 <= din_2;
    din_4 <= din_3;
  end
end
//输入数据缓存
reg signed[15:0] uk_1, uk_2;
always@(posedge clk or negedge rst_n) begin 
  if(!rst_n) begin
    uk_1 <= 16'd0;
    uk_2 <= 16'd0;
  end
  else begin
    uk_1 <= uk;
    uk_2 <= uk_1;
  end
end

在这里插入图片描述
计算 f 1 、 f 2 、 f 3 f1、f2、f3 f1f2f3,其中din_1代表 x ( m ) x(m) x(m),din_2代表 x ( m − 1 ) x(m-1) x(m1),以此类推。采用移位的方法代替乘数0.5,同时注意符号位。
4个16位有符号数相加,其结果有效位数应增加至18位。

wire signed[17:0] f1, f2, f3;//4个16位有符号数相加,拓展2位,即18位
//有符号数,右移时,符号位保持
//f1 = 0.5x(m)-0.5x(m-1)-0.5\x(m-2)+0.5x(m-3)
assign f1 = {{3{din_1[15]}},din_1[15:1]} 
            - {{3{din_2[15]}},din_2[15:1]} 
            - {{3{din_3[15]}},din_3[15:1]} 
            + {{3{din_4[15]}},din_4[15:1]};
//f2 = 1.5x(m-1)-0.5x(m)-0.5x(m-2)-0.5x(m-3)
assign f2 = {{2{din_2[15]}},din_2} + {{3{din_2[15]}},din_2[15:1]} 
            - {{3{din_1[15]}},din_1[15:1]}
            - {{3{din_3[15]}},din_3[15:1]}
            - {{3{din_4[15]}},din_4[15:1]};
//f3 = x(m-2)
assign f3 = {{2{din_3[15]}},din_3};

接下来调用Vivado中的乘法器IP核,计算 f 1 u ( k ) 、 f 2 u ( k ) 、 f 1 u ( k ) u ( k ) f_1u(k)、f_2u(k)、f_1u(k)u(k) f1u(k)f2u(k)f1u(k)u(k),其中uk_1是输入数据uk的缓存,计算 f 1 u ( k ) u ( k ) f_1u(k)u(k) f1u(k)u(k)时需等待 f 1 u ( k ) f_1u(k) f1u(k)的结果出来,同时对其截位至18位(最高位符号位+低17位),并且 f 1 u ( k ) u ( k ) f_1u(k)u(k) f1u(k)u(k)落后了1个时钟周期。另外此时的输入数据uk已经更新,所以也需要提前对其缓存,便有uk_1、uk_2。

wire signed[33:0] f1_u, f2_u, f1_u_u;
mult18_16 u_mult1(
  .CLK(clk),  // input wire CLK 
  .A(f1),     // input wire [17 : 0] A
  .B(uk_1),   // input wire [15 : 0] B
  .P(f1_u)    // output wire [33 : 0] P
);
//f2_u = f2*uk 
mult18_16 u_mult2(
  .CLK(clk),  // input wire CLK
  .A(f2),     // input wire [17 : 0] A
  .B(uk_1),   // input wire [15 : 0] B
  .P(f2_u)    // output wire [33 : 0] P
);
//f1_u_u = f1*uk*uk 此处结果落后1个周期
mult18_16 u_mult3(
  .CLK(clk),
  .A({f1_u[33],f1_u[16:0]}),//取18位有效数据,
  .B(uk_2),
  .P(f1_u_u)
);

在这里插入图片描述

注意到 f 3 f_3 f3已经超前 f 1 u ( k ) u ( k ) f_1u(k)u(k) f1u(k)u(k) 2个时钟周期, f 2 u ( k ) f_2u(k) f2u(k)超前 f 1 u ( k ) u ( k ) f_1u(k)u(k) f1u(k)u(k) 1个时钟周期,于是乎需要提前缓存两者的数据。

//延时 与f1_u_u 对齐
reg signed[33:0] f2_u_1,f3_1, f3_2;
always@(posedge clk or negedge rst_n) begin
  if(!rst_n) begin
    f2_u_1 <= 34'd0;
    f3_1 <= 34'd0;
    f3_2 <= 34'd0;
  end
  else begin
    f2_u_1 <= f2_u;
    f3_1 <= f3;
    f3_2 <= f3_1;
  end
end

最后计算 y 1 ( k ) = f 1 u ( k ) u ( k ) + f 2 u ( k ) + f 3 y_1(k) = f_1u(k)u(k)+f_2u(k)+f_3 y1(k)=f1u(k)u(k)+f2u(k)+f3,以f1_u_u的时序为准对齐即可,此处也需要注意数据截断问题。

reg signed[18:0] dout_reg;
always@(posedge clk or negedge rst_n) begin
  if(!rst_n) begin
    dout_reg <= 19'd0;
  end
  else begin
    dout_reg <= {f1_u_u[33],f1_u_u[17:0]} + {f2_u_1[33],f2_u_1[17:0]} + {f3_2[17],f3_2};
  end
end
assign dout = {dout_reg[18],dout_reg[16:0]};

在这里插入图片描述
最后完整的仿真时序图如下。
在这里插入图片描述
验证:
x ( m ) = 2 , x ( m − 1 ) = 6 , x ( m − 2 ) = 4 , x ( m − 4 ) = 2 f 1 = 1 − 3 − 2 + 1 = − 3 f 2 = 9 − 1 − 2 − 1 = 5 f 3 = 4 u ( k ) = 2 f 1 u ( k ) u ( k ) = − 12 f 2 u ( k ) = 10 y I ( k ) = − 12 + 10 + 4 = 2 , 即 如 图 d o u t = 2 \begin{aligned} &x(m)=2,x(m-1)=6,x(m-2)=4,x(m-4)=2\\ &f_1 =1-3-2+1=-3\\ &f_2=9-1-2-1=5\\ &f_3=4\\ &u(k)=2\\ &f_1u(k)u(k)=-12\\ &f_2u(k)=10\\ &y_I(k)=-12+10+4=2,即如图dout=2 \end{aligned} x(m)=2x(m1)=6x(m2)=4x(m4)=2f1=132+1=3f2=9121=5f3=4u(k)=2f1u(k)u(k)=12f2u(k)=10yI(k)=12+10+4=2dout=2

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值