You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用VHDL抑制信号无用脉冲并计算有效脉冲周期的方法

VHDL实现传感器信号去毛刺与有效脉冲周期计算

核心实现逻辑

  • 第一步先做跨时钟域同步:传感器输出属于异步信号,先打2拍同步到FPGA本地时钟域,规避亚稳态风险。
  • 确定计数阈值:根据所用系统时钟频率,换算1微秒对应的时钟周期数,比如50MHz时钟周期为20ns,1微秒对应50个时钟计数。
  • 电平持续时长统计:用自由计数器记录当前电平的持续时钟数,电平发生翻转时,锁存上一段电平的持续计数值,计数器清零重新开始计数。
  • 毛刺过滤规则:锁存的电平持续时长如果小于等于1微秒对应的计数阈值,直接判定为毛刺丢弃;如果大于阈值,标记为有效脉冲,同时输出锁存的时长作为脉冲周期。

可直接综合的参考代码

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity pulse_proc is
    generic(
        -- 例化时传入实际系统时钟频率,单位Hz
        SYS_CLK_FREQ : integer := 50_000_000
    );
    port(
        clk          : in  std_logic;
        rst_n        : in  std_logic;
        sensor_input : in  std_logic;  -- 传感器原始输入信号
        valid_out    : out std_logic;  -- 有效脉冲标志,高电平持续1个时钟周期
        period_out   : out unsigned(31 downto 0) -- 有效脉冲宽度,单位为时钟周期,乘以时钟周期即可换算为实际时间
    );
end entity pulse_proc;

architecture rtl of pulse_proc is
    constant US1_TICKS : integer := SYS_CLK_FREQ / 1_000_000;
    signal sync_reg    : std_logic_vector(1 downto 0);
    signal sig_sync    : std_logic;
    signal cnt         : unsigned(31 downto 0);
    signal level_latch : std_logic;
begin
    -- 异步信号打两拍同步
    sync_proc: process(clk, rst_n)
    begin
        if rst_n = '0' then
            sync_reg <= (others => '0');
        elsif rising_edge(clk) then
            sync_reg(0) <= sensor_input;
            sync_reg(1) <= sync_reg(0);
        end if;
    end process sync_proc;
    sig_sync <= sync_reg(1);

    -- 脉宽统计与毛刺过滤
    cnt_proc: process(clk, rst_n)
    begin
        if rst_n = '0' then
            cnt <= (others => '0');
            level_latch <= '0';
            valid_out <= '0';
            period_out <= (others => '0');
        elsif rising_edge(clk) then
            valid_out <= '0';
            if sig_sync = level_latch then
                -- 电平未变化,计数累加,到32位最大值后保持不溢出
                if cnt < X"FFFFFFFF" then
                    cnt <= cnt + 1;
                end if;
            else
                -- 电平翻转,判断上一段脉冲是否有效
                if cnt > to_unsigned(US1_TICKS, 32) then
                    valid_out <= '1';
                    period_out <= cnt;
                end if;
                -- 重置计数,锁存新电平
                cnt <= to_unsigned(1, 32);
                level_latch <= sig_sync;
            end if;
        end if;
    end process cnt_proc;
end architecture rtl;

工程使用注意事项

  • 上述代码默认检测高脉冲宽度,如果需要检测低脉冲或者完整高低电平周期,只需调整电平判断逻辑、增加相邻沿时间差锁存逻辑即可。
  • 32位计数位宽可根据实际最大脉冲长度调整,100MHz时钟下32位计数最大可覆盖约42秒的脉冲长度,绝大多数场景足够使用。
  • 建议给1微秒阈值留10%左右的余量,比如实际判断阈值设为1.1微秒对应的计数,避免信号抖动、时钟偏差导致的误判。

硬件层面先确认传感器输出电平与FPGA IO电平匹配,必要时加电平转换芯片,逻辑无法修正硬件电平不匹配导致的信号错误。

内容的提问来源于stack exchange,提问作者PRASHANTH KUMAR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:48:35