• 基于FPGA的高速数据采集系统实现


    欢迎订阅《FPGA学习入门100例教程》、《MATLAB学习入门100例教程

    目录

    一、理论基础

    二、核心程序

    2.1锁存器模块

    2.2双口地址计数器模块

    2.3双口RAM模块

    2.4时钟分频模块

    三、测试结果


    一、理论基础

           高速数据采集在军用民用领域都有着广泛的应用。高速数据采集系统在自动控制、电气测量、地质物探、航空航天等工程实践中有着极为广泛的应用。如何对高速的信号进行实时采集、实时存储,保证信号不丢失,以满足工业现场的需要,一直是高速数据采集系统研究的一个重要方向。数据采集系统是信号与信息处理系统中不可缺少的重要组成部分,同时也是软件无线电系统中的核心模块。

          高速数据采集系统主要包括以下几个部分:模拟信号调理电路、模数转换器、数据处理器件、数据存储器件、时钟电路、触发电路、传输接口芯片和电源系统等,如图1所示。

    图1 高速数据采集系统结构图

          其中,模拟信号调理电路是用来将模拟信号放大调整到ADC的采样量程之内,这样既能充分发挥ADC的性能,又能保证采样数据的完整性;ADC是高速数据采集系统的核心器件,模拟信号输入,数字信号输出;数据处理器件有很多种,可以根据实际的不同需要进行选择;数据存储器件主要用于存储数据,可以进行显示,回放和数据处理等操作;时钟电路是比较重要的,时钟的稳定性和精确性决定着数据采集的结果,所以一般的做法是单独设计稳定的时钟电路;触发电路实现外部对数据采集频率和次数的控制,传输接口用于将数据传输给计算机进行后处理。

               采用单路高速A/D转换器以及存储器构成串行采集系统系统框图如图2所示:

    图2 单路高速数据采集框图

           采用单路高速AD转换器和高速存储电路来构成字串行采集系统,系统的采样就属于实时采样,适用于任何形式的信号波形,重复的或不重复的,单次的或连续的。又由于所有采样点是以时间为顺序,因而易于实现波形显示功能。但是采用单片高速A/D芯片和高速存储器件,会大大提高系统开发成本。同时系统的采样率就受到A/D转换器最高转换速率以及存储器写入速度的限制。因此,单通道数据采集系统的采集速度受器件自身参数的限制,很难再大幅度提高其转换速度。

    二、核心程序

    其整体结构如下所示:

    2.1锁存器模块

            系统工作的时候要对数据进行锁存,然后进行传输,通常这样做可以使系统更加稳定的工作,其工作原理比较简单,实现代码如下所示:

    1. library ieee;
    2. use ieee.std_logic_1164.all;
    3. use ieee.std_logic_unsigned.all;
    4. entity dlatch8 is
    5. port(
    6.    cp: in std_logic;
    7.    d:  in std_logic_vector(7 downto 0);
    8.    q:  out std_logic_vector(7 downto 0)
    9.    );
    10. end dlatch8;
    11. architecture one of dlatch8 is
    12. begin
    13.    process(cp,d)
    14.    begin
    15.       if(cp='1') then
    16.       q<=d;
    17.       end if;
    18.    end process;
    19. end;

    2.2双口地址计数器模块

           地址计数器用来给RAM存储器产生地址信号。由RAM的写入时钟来控制,每当时钟上升沿到来一次,地址计数器就自动加1,直到进行至RAM的底部,表示此时RAM已经写满。下面给出由VHDL语言实现的地址计数器部分源代码。

    1. library ieee;
    2. use ieee.std_logic_1164.all;
    3. use ieee.std_logic_unsigned.all;
    4. use ieee.std_logic_arith.all;
    5. entity addrcount is
    6.       port(
    7.            clr:in std_logic;
    8.            clk:in std_logic;
    9.            eoc: out std_logic;
    10.            q: buffer std_logic_vector(6 downto 0)
    11.           );
    12.         end;
    13. architecture beha of addrcount is
    14. begin
    15.    process(clr,clk)
    16.    begin
    17.       if(clk'event and clk='1') then
    18.               if clr='0'then
    19.               q<="0000000";
    20.           elsif(q="1111111")then
    21.               q<="1111111";
    22.           else
    23.               q<=q+1;
    24.           end if;
    25.       end if;
    26.    end process;
    27.    process(q)
    28.       begin
    29.       if(q="1111111") then
    30.       eoc<='0';
    31.       else
    32.       eoc<='1';
    33.       end if;
    34.    end process;
    35. end beha;

    2.3双口RAM模块

           对于高速数据接收,一般发送端和接收端的时钟是异步的,这就涉及到异步时钟域数据的传输的问题,此外在不同时钟控制的时钟域中传递数据时,了避免发生亚稳态和产生毛刺,应该做好异步时钟域之间的隔离处理。通常,可采用DPRAM以数据缓冲的形式来作为异步时钟域之间的隔离接口。

    1. LIBRARY ieee;
    2. USE ieee.std_logic_1164.all;
    3. LIBRARY altera_mf;
    4. USE altera_mf.all;
    5. ENTITY lpm_ram_dp IS
    6. PORT
    7. (
    8. clock : IN STD_LOGIC ;
    9. data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
    10. rdaddress : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
    11. wraddress : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
    12. wren : IN STD_LOGIC := '1';
    13. q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
    14. );
    15. END lpm_ram_dp;
    16. ARCHITECTURE SYN OF lpm_ram_dp IS
    17. SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
    18. COMPONENT altsyncram
    19. GENERIC (
    20. address_aclr_a : STRING;
    21. address_aclr_b : STRING;
    22. address_reg_b : STRING;
    23. indata_aclr_a : STRING;
    24. intended_device_family : STRING;
    25. lpm_type : STRING;
    26. numwords_a : NATURAL;
    27. numwords_b : NATURAL;
    28. operation_mode : STRING;
    29. outdata_aclr_b : STRING;
    30. outdata_reg_b : STRING;
    31. power_up_uninitialized : STRING;
    32. read_during_write_mode_mixed_ports : STRING;
    33. widthad_a : NATURAL;
    34. widthad_b : NATURAL;
    35. width_a : NATURAL;
    36. width_b : NATURAL;
    37. width_byteena_a : NATURAL;
    38. wrcontrol_aclr_a : STRING
    39. );
    40. PORT (
    41. wren_a : IN STD_LOGIC ;
    42. clock0 : IN STD_LOGIC ;
    43. address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
    44. address_b : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
    45. q_b : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
    46. data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0)
    47. );
    48. END COMPONENT;
    49. BEGIN
    50. q <= sub_wire0(7 DOWNTO 0);
    51. altsyncram_component : altsyncram
    52. GENERIC MAP (
    53. address_aclr_a => "NONE",
    54. address_aclr_b => "NONE",
    55. address_reg_b => "CLOCK0",
    56. indata_aclr_a => "NONE",
    57. intended_device_family => "Cyclone",
    58. lpm_type => "altsyncram",
    59. numwords_a => 256,
    60. numwords_b => 256,
    61. operation_mode => "DUAL_PORT",
    62. outdata_aclr_b => "NONE",
    63. outdata_reg_b => "CLOCK0",
    64. power_up_uninitialized => "FALSE",
    65. read_during_write_mode_mixed_ports => "DONT_CARE",
    66. widthad_a => 8,
    67. widthad_b => 8,
    68. width_a => 8,
    69. width_b => 8,
    70. width_byteena_a => 1,
    71. wrcontrol_aclr_a => "NONE"
    72. )
    73. PORT MAP (
    74. wren_a => wren,
    75. clock0 => clock,
    76. address_a => wraddress,
    77. address_b => rdaddress,
    78. data_a => data,
    79. q_b => sub_wire0 ); END SYN;

    2.4时钟分频模块

           一般在高速系统中,时钟的生产有两种方法实现,PLL锁相环法和计数器分频法。下面我们对两种方法做简单的介绍。

        计数器分频器的设计比较简单,其主要通过计数器来控制时钟发现跳板的周期,这里我们对其工作原理就不做介绍了。本系统由于使用的分频器比较简单,因此在这个系统中,我们将实用计数器分频器来设计时钟。

        其实现的VHDL代码如下所示:

    1. LIBRARY IEEE;
    2. use ieee.std_logic_1164.all;
    3. use ieee.std_logic_unsigned.all;
    4. entity fredivid is
    5. port(
    6.      clkin:in std_logic;
    7.      clkout: out std_logic
    8.     );
    9. end fredivid;
    10. architecture one of fredivid is
    11.              signal q:std_logic_vector(1 downto 0);
    12. begin
    13.      process(clkin)
    14.      begin
    15.          if(clkin'event and clkin='1')then
    16.              if(q="11")then
    17.              q<="00";
    18.          else
    19.              q<=q+1;
    20.          end if;
    21.      end if;
    22.      end process;
    23.      process(q)
    24.      begin
    25.          if(q(1)='1') then
    26.          clkout<='1';
    27.      else
    28.          clkout<='0';
    29.          end if;
    30.      end process; end;

    三、测试结果

         最后,对于设计完成的系统,我们得对其资源做分析。本系统其资源实用情况如所示:

    图1 资源使用分析

    本系统,我们共实用逻辑单元2048个。

    图2 时序分析报表

         其中tsu,tco,tpd,th分别为7.098ns,14.272ns,9.109ns,0.227ns。后面的输入信号频率基本在200M左右,达到高速传输的要求。

    A28-35

  • 相关阅读:
    MySQL报错:this is incompatible with sql_mode=only_full_group_by 解决方法
    一个 Java 对象到底有多大?
    动态规划之线性DP
    CocosCreator 面试题(七)优化cocos creator 包体体积
    TCP/IP第一章概述总结
    JVM类的加载机制
    《前端运维》二、Nginx--3静态资源服务、跨域与其他
    【电梯控制系统】基于VHDL语言和状态机实现的电梯控制系统的设计,使用了状态机
    说一说 Backscatter communication
    Python实现猎人猎物优化算法(HPO)优化卷积神经网络分类模型(CNN分类算法)项目实战
  • 原文地址:https://blog.csdn.net/ccsss22/article/details/128045976