← 数字电路笔试题目总结

推荐答案 测试一下

用VERILOG或VHDL写一段代码,实现消除一个glitch(毛刺)

编程题 中等 笔试真题

参考答案

实现glitch(毛刺)消除的常用方法有:两级/三级触发器同步(适用于较窄毛刺)或计数器滤波(适用于任意宽度毛刺)。以下给出两种典型实现。 方法一:两级触发器同步(适用于毛刺宽度小于时钟周期的情况) ```verilog module glitch_remover ( input clk, input rst_n, input data_in, output data_out ); reg q1, q2; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin q1 <= 1'b0; q2 <= 1'b0; end else begin q1 <= data_in; q2 <= q1; end end assign data_out = q2; endmodule ``` 该代码通过两级寄存器打拍,将异步信号同步到本地时钟域。第一级寄存器可能采样到毛刺(若毛刺宽度满足建立保持时间),但第二级寄存器采样第一级的输出,由于第一级输出可能因亚稳态而振荡,但经过一个时钟周期后大概率稳定,因此第二级输出基本消除亚稳态。若毛刺宽度小于时钟周期,第一级可能采样不到毛刺,从而直接滤除。但此方法不能保证完全消除大于一个时钟周期的毛刺。 方法二:计数器滤波(适用于任意宽度毛刺,可设定稳定阈值) ```verilog module glitch_remover #(parameter CNT_WIDTH=4, STABLE_TH=4) ( input clk, input rst_n, input data_in, output reg data_out ); reg [CNT_WIDTH-1:0] cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin cnt <= 0; data_out <= 0; end else begin if (data_in != data_out) begin if (cnt == STABLE_TH-1) begin data_out <= data_in; cnt <= 0; end else begin cnt <= cnt + 1; end end else begin cnt <= 0; end end end endmodule ``` 该方法在输入与输出不同时启动计数器,仅当输入连续保持STABLE_TH个时钟周期不变时,才更新输出,从而滤除所有宽度小于STABLE_TH-1个时钟周期的毛刺。阈值可根据实际毛刺最大宽度设置。 注意事项: - 组合逻辑毛刺(如因路径延迟差异产生)可通过在组合逻辑输出后加寄存器消除。 - 跨时钟域的毛刺消除需结合同步器和滤波,单靠触发器同步可能无法滤除宽毛刺。 - 实际应用中需考虑毛刺宽度与时钟频率的关系,选择合适的滤波策略。

涉及知识点

  • VERILOG
  • 时钟
  • verilog
  • STA
← 上一题
登录后反馈错题
下一题 →