用于VHDL中ECG去噪的低通FIR滤波器

在这个 VHDL项目,简单的低通 冷杉 过滤器在VHDL中实现 心电图 去噪。完整显示了FIR滤波器的VHDL代码。 

冷杉的VHDL代码 过滤 通过将Modelsim中的模拟结果与Matlab生成的正确结果进行比较,对模型进行了仿真和验证。 input.txt文件中提供了示例ECG输入,VHDL过滤器代码读取这些ECG文件,应用数字过滤,然后将结果写入output.txt文件中进行验证。 


冷杉滤波器的VHDL代码

显然,ECG数字信号处理中最关键的步骤之一就是噪声过滤,因为ECG信号受到许多不同来源(例如基线漂移,EMG干扰和电力线噪声)的干扰。如上图所示,可以通过许多滤波器来减少这些噪声。该项目将在VHDL中实现一个低通FIR滤波器,以减少高频噪声和电力线干扰。

过滤器的规格如下:

  • 订购:10 
  • 抽头:11
  • 8位带符号整数系数,如下所示:
冷杉滤波器的VHDL代码


在本项目中,下图所示的FIR滤波器的常规实现是在VHDL中实现的。


冷杉滤波器的VHDL代码

冷杉滤波器基本上是通过使用D型触发器,有符号乘法器和加法器来实现的。一个基本块包括一个N位寄存器,一个乘法器和一个加法器。 VHDL generate语句用于使用基本块生成完整的设计。

低通FIR滤波器的VHDL代码:

Library IEEE;  
 USE IEEE.Std_logic_1164.all;   
 USE IEEE.Std_logic_signed.all;   
 -- fpga4student.com: FPGA projects, VHDL项目, Verilog projects   
 -- LOW pass 冷杉 过滤 for 心电图 Denoising
 -- VHDL项目: 冷杉滤波器的VHDL代码   
 entity 冷杉_RI is  -- VHDL项目
 generic (  
           input_width          : integer     :=8               ;-- set input width by user  
           output_width     : integer     :=16               ;-- set output width by user  
           coef_width          : integer     :=8               ;-- set coefficient width by user  
           tap                    : integer     :=11               ;-- set 过滤 order  
           guard               : integer     :=0)               ;-- log2(tap)+1  
 port(  
      Din          : in      std_logic_vector(input_width-1 downto 0)     ;-- input data  
      Clk          : in      std_logic                                             ;-- input clk  
      reset     : in      std_logic                                             ;-- input reset  
      Dout     : out      std_logic_vector(output_width-1 downto 0))     ;-- output data  
 end 冷杉_RI;  
 architecture behaivioral of 冷杉_RI is  
 -- N bit Register  
 component N_bit_Reg   
 generic (  
           input_width          : integer     :=8  
           );  
   port(  
    Q : out std_logic_vector(input_width-1 downto 0);     
    Clk :in std_logic;    
    reset :in std_logic;   
    D :in std_logic_vector(input_width-1 downto 0)    
   );  
 end component;
 -- fpga4student.com: FPGA projects, VHDL项目, Verilog projects  
 type Coeficient_type is array (1 to tap) of std_logic_vector(coef_width-1 downto 0);  
 -----------------------------------FIR 过滤 coefficients----------------------------------------------------------------  
 constant coeficient: coeficient_type :=   
                               (     X"F1",  
                                    X"F3",  
                                    X"07",  
                                    X"26",  
                                    X"42",  
                                    X"4E",  
                                    X"42",  
                                    X"26",  
                                    X"07",  
                                    X"F3",  
                                    X"F1"                                     
                                    );                                         
 ----------------------------------------------------------------------------------------------                                     
 type shift_reg_type is array (0 to tap-1) of std_logic_vector(input_width-1 downto 0);  
 signal shift_reg : shift_reg_type;  
 type mult_type is array (0 to tap-1) of std_logic_vector(input_width+coef_width-1 downto 0);  
 signal mult : mult_type;  
 type ADD_type is array (0 to tap-1) of std_logic_vector(input_width+coef_width-1 downto 0);  
 signal ADD: ADD_type;  
 begin  
 -- fpga4student.com: FPGA projects, VHDL项目, Verilog projects
        shift_reg(0)     <= Din;  
           mult(0)<= Din*coeficient(1);  
           ADD(0)<= Din*coeficient(1);  
           GEN_FIR:  
           for i in 0 to tap-2 generate  
           begin  
                 -- N-bit reg unit  
                 N_bit_Reg_unit : N_bit_Reg generic map (input_width => 8)   
                 port map ( Clk => Clk,   
                                    reset => reset,  
                                    D => shift_reg(i),  
                                    Q => shift_reg(i+1)  
                                    );       
                -- 过滤 multiplication  
                mult(i+1)<= shift_reg(i+1)*coeficient(i+2);  
                -- 过滤 conbinational addition  
                ADD(i+1)<=ADD(i)+mult(i+1);  
           end generate GEN_FIR;  
           Dout <= ADD(tap-1);  
 end Architecture;  

 Library IEEE;  
 USE IEEE.Std_logic_1164.all;  
 
 -- fpga4student.com: FPGA projects, VHDL项目, Verilog projects   
 -- LOW pass 冷杉 过滤 for 心电图 Denoising
 -- VHDL项目: 冷杉滤波器的VHDL代码
 -- N-bit Register in VHDL 
 entity N_bit_Reg is   
 generic (  
           input_width          : integer     :=8  
           );  
   port(  
    Q : out std_logic_vector(input_width-1 downto 0);    
    Clk :in std_logic;    
    reset :in std_logic;  
    D :in std_logic_vector(input_width-1 downto 0)    
   );  
 end N_bit_Reg;  
  -- fpga4student.com: FPGA projects, VHDL项目, Verilog projects  
 architecture Behavioral of N_bit_Reg is   
 begin   
      process(Clk,reset)  
      begin   
           if (reset = '1') then  
                Q <= (others => '0');  
        elsif ( rising_edge(Clk) ) then  
                Q <= D;   
       end if;      
      end process;   
 end Behavioral;

冷杉滤波器的Testbench VHDL代码:

 Library IEEE;  
 USE IEEE.Std_logic_1164.all;    
 USE IEEE.numeric_std.all;  
 Use STD.TEXTIO.all;  
  -- fpga4student.com: FPGA projects, VHDL项目, Verilog projects
  -- VHDL项目: 冷杉滤波器的VHDL代码 
  -- Testbench 冷杉滤波器的VHDL代码 
 entity TB_FIR is  
 end TB_FIR; 
 architecture behaivioral of TB_FIR is  
 Component 冷杉_RI is  
 generic (  
           input_width          : integer     :=8               ; -- set input width by user  
           output_width     : integer     :=16               ; -- set output width by user  
           coef_width          : integer     :=8               ; -- set coefficient width by user  
           tap                    : integer     :=11               ; -- set 过滤 order  
           guard               : integer     :=4)                    ; -- log2(tap)+1  
 port(  
      Din          : in      std_logic_vector(input_width-1 downto 0)     ;     -- input data  
      Clk          : in      std_logic                              ;               -- input clk  
      reset     : in      std_logic                                   ;               -- input reset  
      Dout     : out      std_logic_vector(output_width-1 downto 0))     ;-- output data  
 end Component;  
 signal Din          :      std_logic_vector(7 downto 0)     ;  
 signal Clk          :      std_logic:='0'                              ;  
 signal reset     :      std_logic:='1'                              ;       
 signal output_ready     :      std_logic:='0';                                
 signal Dout          :      std_logic_vector(15 downto 0)     ;  
 signal input: std_logic_vector(7 downto 0);  
 file my_input : TEXT open READ_MODE is "input101.txt";  
 file my_output : TEXT open WRITE_MODE is "output101_functional_sim.txt";  
 begin  
   -- fpga4student.com: FPGA projects, VHDL项目, Verilog projects
   冷杉_int : 冷杉_RI  
           generic map(  
                          input_width          =>     8,  
           output_width     =>     16,  
           coef_width          =>     8,  
           tap                 =>     11,  
                          guard               =>     0)  
           port map     (  
                          Din                    => Din,  
                          Clk                    => Clk,  
                          reset               => reset,  
                          Dout               => Dout  
                );  
           process(clk)  
           begin  
           Clk          <= not Clk after 10 ns;  
           end process;  
           reset     <= '1', '1' after 100 ns, '0' after 503 ns; 
     -- fpga4student.com: FPGA projects, VHDL项目, Verilog projects 
     -- Writing output result to output file 
           process(clk)  
           variable my_input_line : LINE;  
           variable input1: integer;  
           begin  
                if reset ='1' then  
                     Din <= (others=> '0');  
                     input <= (others=> '0');  
                     output_ready <= '0';  
                elsif rising_edge(clk) then                      
                     readline(my_input, my_input_line);  
                     read(my_input_line,input1);  
                     Din <= std_logic_vector(to_signed(input1, 8));  
                     --Din<=input(7 downto 0);  
                     output_ready <= '1';  
                end if;  
           end process;                      
           process(clk)  
           variable my_output_line : LINE;  
           variable input1: integer;  
           begin  
                if falling_edge(clk) then  
                     if output_ready ='1' then  
                          write(my_output_line, to_integer(signed(Dout)));  
                          writeline(my_output,my_output_line);  
                     end if;  
                end if;  
           end process;   
                                
 end Architecture; 
在Modelsim中运行仿真后,将过滤后的输出写入output.txt中进行验证。通过将输出文件与Matlab生成的正确结果进行比较来完成验证。
从Matlab下载示例输入和输出


推荐的 VHDL项目:
1. 什么是FPGA? VHDL如何在FPGA上工作
2. FIFO存储器的VHDL代码
3. 冷杉滤波器的VHDL代码
4. 8位微控制器的VHDL代码
5. 矩阵乘法的VHDL代码
6. 开关尾环计数器的VHDL代码
7. FPGA上数字闹钟的VHDL代码
8. 8位比较器的VHDL代码
9. 如何使用VHDL将文本文件加载到FPGA中
10。 D触发器的VHDL代码
11。 完整加法器的VHDL代码
12 具有可变占空比的VHDL中的PWM发生器
13 ALU的VHDL代码
14。 带测试平台的计数器的VHDL代码
15 16位ALU的VHDL代码
16。 VHDL中的移位器设计
17。 VHDL中的非线性查找表实现
18岁 VHDL中的密码协处理器设计

19 Verilog和VHDL:通过示例解释
20 FPGA上时钟分频器的VHDL代码
21 如何生成时钟使能信号而不是创建另一个时钟域
22 VHDL代码,用于反跳FPGA上的按钮
23。 交通信号灯控制器的VHDL代码
24 用于简单2位比较器的VHDL代码
25岁 单端口RAM的VHDL代码
22 VHDL代码,用于反跳FPGA上的按钮
23。 交通信号灯控制器的VHDL代码
24 用于简单2位比较器的VHDL代码
25岁 单端口RAM的VHDL代码
26  使用FSM的停车场系统的VHDL代码
27。 VHDL编码与软件编程
FPGA Verilog VHDL课程

29条评论:

  1. 想要在Arty板上进行此操作,但是很难配置ADC。对ADC接口有帮助吗?

    回复删除
    回覆
    1. 查找ADC芯片或模块,例如MCP3001或PMOD ADC Digilent

      删除
  2. 回覆
    1. 这是FIR滤波器的常规实现。它不是通过使用频率采样方法来设计的。

      删除
  3. 嘿,
    I'在代码中此行有问题:write(my_output_line,to_integer(signed(Dout))); ISE中的编译器说:"write的第二个参数必须具有恒定值". I dont'知道如何解决此问题。谢谢你的帮助

    回复删除
    回覆
    1. 您编译或合成了测试平台,'s为什么会出现该错误。您只能在测试平台上运行模拟。仅合成顶层(FIR_RI)。

      删除
    2. 感谢您的快速帮助。是的,的确,我'编译了测试平台。因此,测试台只需要作为一个模块编写,我认为它是编译的主要模块(顶层)?对不起'm a beginner !!

      删除
  4. 谢谢您提供的代码,我在输入输出和系数宽度方面遇到问题。它们是什么用于kaiser窗口或如何计算?

    回复删除
  5. 嗨Loi,
    Mìnhgặplỗinàykhichạy模拟。"无法打开文件input101.txt"
    Mìnhđã下载文件输入vềnhưngchưabiếtphảiđặtvàothưmục
    Mìnhcầnphảiđặtvàođâunhỉ?
    Cảmơnbạn!

    回复删除
  6. 有没有人实现此过滤器的MATLAB程序能够提供相同的输出?我尝试使用该项目中的系数创建FIR滤波器,但得到的输出却完全不同。

    回复删除
    回覆
    1. 如果使用此VHDL代码,则将生成与Matlab相同的输出。

      删除
  7. 它也可以在xilinx ise上工作吗?

    回复删除
  8. 嗨,范。谢谢你的代码。

    我怀疑您已通过文本基准应用了文本输入,然后如何将其应用于fpga。

    回复删除
    回覆
    1. 在这种情况下,您需要创建一个可综合模型,以将文本文件数据传递到FIR滤波器。

      删除
  9. 它适用于Altera Quartus Prime吗?如何获取输入文件?

    回复删除
  10. Cho emhỏi,复制代码为vàofile .vht,从此开始编译khôngcólỗigì。 Nhưngkhivào文件夹ch simulationy模拟(đãcó文件输入trongđó)thìkhôngthôy文件输出đuôi.txtđâu。 Khôngbiếtđâylàlỗigìhaycáchemchạymôphỏngbịsai? Mongđượcgiúpđỡ。 Em Quartus II 121。

    回复删除
    回覆
    1. 您必须运行仿真,直到output_ready ='1'这样就写入了输出文件。

      删除
  11. 提供的链接中不再包含样本输入和输出文件。我要求您再次提供。

    回复删除
  12. 我确实运行过Modelim Simulator'input101.txt'文件放在项目文件夹中。我有'output101_functional_sim.txt'与以下文件不同的文件'output101.txt'您在链接中提供的示例文件。
    中的值数'output101_functional_sim.txt'文件远远少于中的值数量'output101.txt'文件。请对此提供帮助。

    回复删除
    回覆
    1. 仔细检查您的模拟。验证了代码,并且所有输出与提供的样本大致匹配。

      删除
  13. 首先感谢您的代码,
    其次,您能否提供示例输入和输出文件("input101.txt" and "output101_functional_sim.txt").

    回复删除
  14. 嗨,我可以在papillo逻辑启动上使用此代码。硬件要求是什么

    回复删除
  15. 您使用哪个滤波器窗口获取系数

    回复删除
  16. 嗨,我有一个关于滤波器系数的问题,如何得到整数?我得到的问题是,我已经获得了内置的低通滤波器(Butterworh)的系数,它是如此之小,如何将这个小数转换为VHDL?谢谢!

    回复删除

热门FPGA项目