微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 一个关于IIR滤波器的代码(VHDL)仿真问题

一个关于IIR滤波器的代码(VHDL)仿真问题

时间:10-02 整理:3721RD 点击:
小弟在Meyer-Baese的《数字信号处理的FPGA实现》(相信此牛书在这个论坛能找到)看到了一段IIR的代码如下:
PACKAGE n_bit_int IS             -- User defined type
  SUBTYPE BITS15 IS INTEGER RANGE -2**14 TO 2**14-1;
END n_bit_int;
LIBRARY work;
USE work.n_bit_int.ALL;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
ENTITY my_iir_3 IS
  PORT ( x_in  : IN   BITS15;   -- Input
         y_out : OUT  BITS15;   -- Result
         clk   : IN   STD_LOGIC);
END my_iir_3;
ARCHITECTURE flex OF my_iir_3 IS
  SIGNAL  x, x3, sx, y, y9 : BITS15;
            
BEGIN
  PROCESS  -- Use FFs for input, output and pipeline stages
  BEGIN
    WAIT UNTIL clk = '1';
    x   <= x_in;
    x3  <= x / 2 + x / 4;                 -- Compute x*3/4
    sx <=  x + x3;                     -- Sum of x element i.e. output FIR part
    y9  <= y / 2 + y / 16;           -- Compute y*9/16
    y   <= sx + y9;                       -- Compute output
  END PROCESS;
  y_out <= y ;                   -- Connect register y to output pins
  
END flex;
用Quartus II 7.0仿真,输入x_in取为一个时钟周期的正整数1000,发现结果严重错误,仔细察看各信号和变量后发现问题在于Quartus II 7.0在处理正整数时会莫名将最高符号位置1,导致正数全变负数,结果相差十万八千里。
作者用的是MUXplusII编译仿真的,结果正常,会不会是这两种编译器对整数的处理存在差异?我没有MuxplusII,还未做此比照。
小弟发现一解决办法是将整数的范围设定为0 to 2**14-1,Quartus II 7.0仿真结果立马正确。
然而,实际处理问题时回避处理负整数是一个不明智的选择,中间计算过程如有减法,则难保不够减即出现负数溢出的情况。
此外小弟也尝试用一些数据类型转换的函数,也没有解决这个问题。
翻看书后所附的相应的verilog代码后发现,处理数据不分正负,即全部按位矢量处理,由于我目前对verilog还不熟悉,故还未对该verilog代码仿真
望论坛里各位牛人能提点一二,小弟感激不尽!
附相应的verilog代码如下:
module iir_pipe (x_in, y_out, clk); //----> Interface
  parameter W = 14; // Bit width - 1
  input          clk;
  input  [W:0]  x_in;   // Input
  output [W:0]  y_out;  // Result
  reg [W:0] x, x3, sx;
  reg [W:0] y, y9;  
            
  always @(posedge clk)  // Infer FFs for input, output and
  begin                                                              // pipeline stages;
    x   <= x_in;                                                       // use non-blocking FF assignments
    x3  <= {x[W],x[W:1]} + {x[W],x[W],x[W:2]};           // i.e. x / 2 + x / 4 = x*3/4
    sx  <= x + x3;                                                  // Sum of x element i.e. output FIR part
    y9  <= {y[W],y[W:1]} + {{4{y[W]}},y[W:4]};        // i.e. y / 2 + y / 16 = y*9/16
    y   <= sx + y9;                                                // Compute output
  end
  assign y_out = y ;   // Connect register y to output pins
endmodule

自己顶一下,免得沉了

我再顶起来

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top