关于毛刺

信号在FPGA器件中通过逻辑单元连线时,一定存在延时。延时的大小不仅和连线的长短和逻辑单元的数目有关,而且也和器件的制造工艺、工作环境等有关。因 此,信号在器件中传输的时候,所需要的时间是不能精确估计的,当多路信号同时发生跳变的瞬间,就产生了“竞争冒险”。这时,往往会出现一些不正确的尖峰信 号,这些尖峰信号就是“毛刺”。

数字电路中常将毛刺定义为采样间越过逻辑门限一次以上的任何跳变,主要是指电路输出波形中含有时间很短有规律或没有规律的脉冲而又对设计没有用处或产生其他影响。

 

消除毛刺的一般方法有以下几种:

1.利用冗余项消除毛刺
   函数式和真值表所描述的是静态逻辑,而竞争则是从一种稳态到另一种稳态的过程。因此竞争是动态过程,它发生在输入变量变化时。此时,修改卡诺图,两个卡诺 图圈相切处增加一个冗余的卡诺图圈,在卡诺图的两圆相切处增加一个圆,可以消除逻辑冒险。但该法对于计数器型产生的毛刺是无法消除的。如对图1 电路的函数为OUT=A·B+C·D,其有冒险函数的卡诺图如图3所示,可以看出图中有卡诺图圆相切的现象,在此相切处增加一项A·B·C·D,即逻辑函 数变为OUT=A·B+C·D+A·B·C·D,此函数将不会有逻辑冒险即毛刺产生。

2.通过改变设计,破坏毛刺产生的条件,来减少毛刺的发生
    例如,在数字电路设计中,常常采用格雷码计数器取代普通的二进制计数器,这是因为格雷码计数器的输出每次只有一位跳变,消除了竞争冒险的发生条件,避免了毛刺的产生。
3.在系统中尽可能采用同步电路
    毛刺并不是对所有的输入都有危害,例如D触发器的D输入端,只要毛刺不出现在时钟的上升沿并且满足数据的建立和保持时间,就不会对系统造成危害,因此可以 说D触发器的D输入端对毛刺不敏感。 根据这个特性,应当在系统中尽可能采用同步电路,这是因为同步电路信号的变化都发生在时钟沿,只要毛刺不出现在时钟的沿口并且不满足数据的建立和保持时 间,就不会对系统造成危害。由于毛刺很短,多为几纳秒,基本上都不可能满足数据的建立和保持时间。因此如果在输出信号的保持时间内对其进行“采样”,就可以消除毛刺信号的影响。
    例如对图1中的电路,我们做出如图4所示的改进,在输出信号的保持时间内,用一定宽度的高电平脉冲与输出信号做逻辑“与”运算,由此获取输出信号的电平值。图4中从输入引脚“SAMPLE”引入采样脉冲信号。从图5的仿真波形上可以看出,毛刺信号出现在“TEST”引脚上,而“OUT”引脚上的毛刺已被消除了。
4.待信号稳定之后进行取样
    由于冒险出现在变量发生变化的时刻,如果待信号稳定之后加入取样脉冲,那么就只有在取样脉冲作用期间输出的信号才能有效,这样可以避免产生的毛刺影响输出波形。

5.输出端增加输出电容
   增加输出滤波,在输出端接上小电容C可以滤除毛刺,如图6所示。但输出波形的前后沿将变坏,在对波形要求较严格时,应再加整形电路,该方法不宜在中间级使用。

 

转载于:https://www.cnblogs.com/daisyuer/p/7455271.html

<think>我们参考了用户提供的引用资料,特别是引用[3]和[4]中关于毛刺滤波的Verilog实现方法。用户希望设计一个毛刺滤波器,用于滤除信号中的毛刺(glitch)。根据引用[3],毛刺滤波的基本原理是:当信号出现跳变时,启动一个计数器,如果在计数器计满之前信号再次跳变,则认为是毛刺,不输出变化;只有当信号稳定一定时间(计数器计满)后,才将变化输出。引用[4]给出了一个具体的实现代码,该代码通过检测信号边沿,然后计数,当计数到最大值时输出稳定后的信号。 根据这些原理,我们设计一个毛刺滤波器,主要参数是毛刺的最大宽度(以时钟周期为单位)。假设我们要滤除的毛刺宽度最大为N个时钟周期,那么我们需要计数器计数到N+1(或N,根据具体设计)才认为信号稳定。这里我们设计一个可配置的毛刺滤波器,其中计数器位数可以根据需要滤除的毛刺宽度来设定。设计思路: 1.输入信号:clk,rst_n, data_in2.输出信号:data_out(滤除毛刺后的信号)3.边沿检测:检测输入信号的跳变(上升沿或下降沿),一旦检测到跳变,就复位计数器并开始计数。 4.计数规则:在边沿检测后的每个周期,如果信号没有再次跳变(即保持稳定),则计数器递增;如果再次检测到边沿,则复位计数器(重新开始计数)。5.输出更新:当计数器计满(达到预设值)时,将当前稳定的信号值输出。注意:引用[3]提到,对于宽度介于N和N+1个周期之间的毛刺,需要N+2级触发器采样,然后再进行与(或)操作。但这里我们采用计数器的设计,可以更灵活地适应不同宽度的毛刺。 我们设计一个参数化的毛刺滤波器,其中参数`GLITCH_WIDTH`表示需要滤除的毛刺的最大宽度(单位:时钟周期数)。计数器的位宽设为`$clog2(GLITCH_WIDTH+1)$`(SystemVerilog)或通过计算得到(Verilog)。当计数器计数到`GLITCH_WIDTH`时,认为信号稳定,更新输出。具体代码实现如下(使用Verilog):```verilogmodule glitch_filter#(parameterGLITCH_WIDTH =2//可滤除最大宽度为2个时钟周期的毛刺)(input wireclk,input wirerst_n,input wiredata_in,output regdata_out);//边沿检测:检测输入信号的变化regdata_in_r;wiredata_edge; always@(posedgeclkor negedge rst_n)beginif(!rst_n)data_in_r <=1'b0;elsedata_in_r<= data_in;endassign data_edge =(data_in !=data_in_r);//只要发生跳变就认为是边沿//计数器:位宽根据GLITCH_WIDTH计算localparamCOUNTER_WIDTH =$clog2(GLITCH_WIDTH+1);//计数器需要计到GLITCH_WIDTH,所以位宽为log2(GLITCH_WIDTH+1) reg[COUNTER_WIDTH-1:0]cnt;//状态机:当检测到边沿时复位计数器,否则计数直到达到GLITCH_WIDTHalways @(posedge clk ornegedgerst_n) beginif (!rst_n)cnt<= 'd0;else if(data_edge)//检测到边沿,重置计数器cnt<= 'd0;else if(cnt< GLITCH_WIDTH)//未达到阈值,继续计数cnt<= cnt+1'b1;//否则,cnt保持不变(已经达到最大值) end//输出更新:当计数器达到GLITCH_WIDTH时,更新输出为当前稳定的值(即上一拍的值data_in_r) always@(posedgeclkor negedge rst_n)beginif(!rst_n)data_out<=1'b0;elseif (cnt ==GLITCH_WIDTH)//计数满,说明信号已经稳定了GLITCH_WIDTH个周期,可以更新输出data_out <=data_in_r;//注意:这里使用data_in_r而不是data_in,因为data_in可能刚变化,而data_in_r是上一拍的稳定值endendmodule``` 说明: 1.参数`GLITCH_WIDTH`:表示需要滤除的毛刺的最大宽度(以时钟周期为单位)。例如,设置为2,则可以滤除宽度小于等于2个时钟周期的毛刺。 2.边沿检测:通过比较当前输入和上一拍的输入(`data_in_r`)来检测跳变。一旦检测到跳变(`data_edge`为高),就复位计数器。 3.计数器:在无跳变期间,计数器从0开始递增,直到达到`GLITCH_WIDTH`。如果在此期间再次发生跳变,则计数器复位。 4.输出更新:当计数器达到`GLITCH_WIDTH`时,将上一拍的输入值(`data_in_r`)作为稳定输出。注意,这里使用`data_in_r`而不是`data_in`,因为`data_in_r`已经同步到时钟域,且延迟了一个周期,这样能保证在计数器计满时,该值已经稳定了足够长的时间。 注意:这个设计假设毛刺的最大宽度是已知的,并且毛刺之间的稳定间隔大于毛刺宽度。如果信号稳定时间不足,则可能无法正确输出。 测试:需要编写测试平台,产生带有毛刺的输入信号,验证毛刺滤波器的效果。相关问题:1.如何确定毛刺滤波器中GLITCH_WIDTH参数的最佳值?2.毛刺滤波器对信号延迟的影响是什么?3.除了计数器方法,还有哪些毛刺滤波的实现方式? 4.如何验证毛刺滤波器的性能?参考文献: [^3]: Verilog消除毛刺[^4]:单bit信号进行毛刺滤除(Verilog)</think>### Verilog毛刺滤波器设计指南 参考引用资料[3][^3]和[4][^4],毛刺滤波的核心原理是**信号稳定周期检测**。以下提供两种可配置的Verilog实现方案,支持参数化毛刺宽度阈值。 --- ### **方案1:基于计数器检测的毛刺滤波器** ```verilog module glitch_filter #( parameter GLITCH_WIDTH = 3 // 可滤除≤2周期毛刺(默认值) )( input clk, input rst_n, input data_in, output data_out ); // 边沿检测与稳定周期计数 reg data_in_r; wire data_edge; reg [$clog2(GLITCH_WIDTH+1)-1:0] cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) data_in_r <= 1'b0; else data_in_r <= data_in; end assign data_edge = data_in ^ data_in_r; // 跳变检测[^3] always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt <= 'd0; else if (data_edge) cnt <= 'd0; // 跳变时重置计数 else if (cnt < GLITCH_WIDTH) cnt <= cnt + 1; end // 输出稳定信号 assign data_out = (cnt == GLITCH_WIDTH) ? data_in_r : data_out; endmodule ``` **设计原理**: 1. `data_edge`检测信号跳变,触发计数器归零 2. 计数器达到`GLITCH_WIDTH`阈值时,判定信号稳定 3. 输出延迟 = `GLITCH_WIDTH + 1`个时钟周期 4. 可滤除毛刺宽度范围:$0 < W_{glitch} \leq (GLITCH\_WIDTH - 1)T_{clk}$ **参数配置**: | 毛刺最大宽度 | GLITCH_WIDTH值 | |--------------|----------------| | 1个周期 | 2 | | 2个周期 | 3 | | N个周期 | N+1 | --- ### **方案2:多级寄存器滤波(适合固定宽度毛刺)** ```verilog module glitch_filter_fixed #( parameter STAGES = 3 // 寄存器级数 )( input clk, input rst_n, input data_in, output data_out ); reg [STAGES-1:0] shift_reg; always @(posedge clk or negedge rst_n) begin if (!rst_n) shift_reg <= {STAGES{1'b0}}; else shift_reg <= {shift_reg[STAGES-2:0], data_in}; end // 逻辑选择:滤高电平毛刺用与门,滤低电平毛刺用或门[^3] assign data_out = &shift_reg; // 滤除高电平毛刺 // assign data_out = |shift_reg; // 滤除低电平毛刺 endmodule ``` **设计原理**: 1. $N$级寄存器链对信号采样($N \geq 毛刺宽度/周期+1$) 2. 与门输出(`&shift_reg`):仅当连续$N$周期高电平时输出1 3. 或门输出(`|shift_reg`):仅当连续$N$周期低电平时输出0 4. 滤除能力:$W_{glitch} < (STAGES - 1)T_{clk}$ --- ### **关键设计考量** 1. **时钟频率选择** 系统时钟需满足: $$f_{clk} > \frac{1}{W_{glitch\_max}}$$ 例如滤除5ns毛刺需$f_{clk} \geq 200MHz$[^1] 2. **异步信号处理** 若输入信号跨时钟域,需先进行同步化: ```verilog reg [2:0] sync_chain; always @(posedge clk) sync_chain <= {sync_chain[1:0], async_in}; ``` 3. **时序约束(Xilinx示例)** ```tcl set_max_delay -from [get_ports data_in] -to [get_pins shift_reg_reg[0]/D] 1.0 ``` --- ### **测试平台示例** ```verilog module tb_glitch_filter(); reg clk, rst_n, data_in; wire data_out; glitch_filter uut(.*); initial begin clk = 0; forever #5 clk = ~clk; // 100MHz时钟 end initial begin rst_n = 0; data_in = 0; #20 rst_n = 1; // 生成毛刺测试序列 #10 data_in = 1; // 正常跳变 #8 data_in = 0; // 4ns毛刺(小于阈值) #4 data_in = 1; #30 data_in = 0; // 稳定跳变 #100 $finish; end initial begin $monitor("T=%0t: in=%b out=%b", $time, data_in, data_out); end endmodule ``` --- ### **性能对比** | 方法 | 优势 | 局限性 | 适用场景 | |--------------|-----------------------|----------------------|-----------------------| | 计数器法 | 毛刺宽度可配置 | 输出延迟较大 | 动态变化毛刺 | | 多级寄存器法 | 延迟小(1周期) | 毛刺宽度固定 | 已知毛刺宽度的系统 | | 混合方法 | 结合两者优势 | 设计复杂度高 | 高可靠性系统 | > **提示**:对于高频信号,建议在PCB层面增加RC滤波电路,结合数字滤波实现双重防护[^1][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值