[数字设计]抓外部信号的沿
以下用verilog描述,且只考虑信号上升沿,而下沿同理。
假设外部信号为sig,我们首先想到的会是
always@(posedge sig)
...
似乎没什么错,但这有很多的问题:
第一点,外部信号可能会有很多的毛刺,并非真正的上沿;
第二点,如此设计导致触发器所用时钟彼此不一致,特别对于像fpga之类的东西,综合虽然可以,但并不好。
其中,第一点是致命的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
解决这个问题似乎就有点麻烦了,这是信号干扰很大的情况了。
但方法还是一样存在:我们只辨别缓存为全1的时候认定为高电平,全0认定低电平。
复制代码
问题解决的方法没有掌握之前就是实际问题,掌握之后就是常识了,在解决问题的过程所花的代价(时间,金钱)等就构成了解决问题的成本,能有效地解决问题的方法就是好方法,至于这个方法是高深的还是属于常识的,这属于各个人的主观评价了,但不论大家如何评价,不能否认的是解决了实际问题的这个客观结果.
因此善于解决问题的人和能有效解决问题的方法就是牛!
这不是牛不牛的问题,这是常识,可是初学者却不一定有这样的常识.
对于其原因,我的电脑截图不知为什么出了问题,所以无法截图了.有兴趣的用modelsim仿真一下以下的电路,仔细对照一下波形图,再想想或许就明白了.
复制代码
lz 牛,这样在实际工作中的体会很有实际意义,远比一些纸上谈兵有实际意义.
至于“用一个外部可能有毛刺的信号来作为组合输出,很危险”这一点,请相信我,我有过惨痛的教训。
本帖最后由 cjaizss 于 2010-10-21 13:16 编辑
然后,再滤去一次低电平下的毛刺:
module catch_posedge(rst,clk,sig_posedge,sig);
input rst,clk,sig;
output sig_posedge;
reg [2:0]sig_reg;
always@(posedge rst or posedge clk)
if(rst)
sig_reg[2:0]<=3'b111;
else
sig_reg[2:0]<={sig_reg[1:0],sig};
assign sig_posedge = sig_reg==3'b011;
endmodule
基本成了
全部用内部寄存器来组合输出应该是比较好的选择。
module catch_posedge(rst,clk,sig_posedge,sig);
input rst,clk,sig;
output sig_posedge;
reg sig_reg,sig_reg2;
always@(posedge rst or posedge clk)
if(rst)
{sig_reg,sig_reg2}<=2'b11;
else
{sig_reg,sig_reg2}<={sig,sig_reg};
/*以上写法我多少有点偷工减料,不推荐这么写,还是分开写比较好,好的代码习惯是需要的*/
assign sig_posedge = !sig_reg2 & sig_reg;
endmodule
于是怎么办呢?我们还是要用到系统时钟,缓存一道试下,在上沿处生成单脉宽的一个信号。
module catch_posedge(rst,clk,sig_posedge,sig);
input rst,clk,sig;
output sig_posedge;
reg sig_reg;
always@(posedge rst or posedge clk)
if(rst)
sig_reg<=1'b1;
else
sig_reg<=sig;
assign sig_posedge = !sig_reg & sig;
endmodule
似乎看起来很好了,但其实也只是五十笑百,利用一个外部可能有毛刺的信号来作为组合输出,很危险,出现真正意思上的上沿(并非毛刺)的时候,其附近如果有毛刺,那么就有抓不到的危险。