[数字设计]抓外部信号的沿

发布于 2022-09-13 04:44:02 字数 237 浏览 18 评论 9

以下用verilog描述,且只考虑信号上升沿,而下沿同理。
假设外部信号为sig,我们首先想到的会是
always@(posedge sig)
   ...
似乎没什么错,但这有很多的问题:
第一点,外部信号可能会有很多的毛刺,并非真正的上沿;
第二点,如此设计导致触发器所用时钟彼此不一致,特别对于像fpga之类的东西,综合虽然可以,但并不好。
其中,第一点是致命的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

听风念你 2022-09-19 14:42:07

对于其原因,我的电脑截图不知为什么出了问题,所以无法截图了.有兴趣的用modelsim仿真一下以下的电路,仔细对 ...
cjaizss 发表于 2010-10-20 09:18

    解决这个问题似乎就有点麻烦了,这是信号干扰很大的情况了。
  但方法还是一样存在:我们只辨别缓存为全1的时候认定为高电平,全0认定低电平。

  1.   `timescale 1ns/1ps
  2. module reset_module_test(
  3.                                 gpio,
  4.                                 clk,
  5.                                 rst,
  6.                                 io_out
  7.     );
  8. input gpio,clk,rst;
  9. output io_out;
  10. parameter REG_WILDTH=6;
  11. reg io_out;
  12. reg [REG_WILDTH-1:0]gpio_reg;
  13. wire negedge_gpio, posedge_gpio;
  14. always@(posedge rst or posedge clk)
  15.      if(rst)
  16.              io_out <= 1'b0;
  17.      else if(&gpio_reg)
  18.              io_out <= 1'b1;
  19.      else if(!(|gpio_reg))
  20.              io_out <= 1'b0;
  21. endmodule
  22.    

复制代码

傲世九天 2022-09-19 12:09:18

这不是牛不牛的问题,这是常识,可是初学者却不一定有这样的常识.
cjaizss 发表于 2010-10-20 09:19

    问题解决的方法没有掌握之前就是实际问题,掌握之后就是常识了,在解决问题的过程所花的代价(时间,金钱)等就构成了解决问题的成本,能有效地解决问题的方法就是好方法,至于这个方法是高深的还是属于常识的,这属于各个人的主观评价了,但不论大家如何评价,不能否认的是解决了实际问题的这个客观结果.
   
   因此善于解决问题的人和能有效解决问题的方法就是牛!

梦毁影碎の 2022-09-19 10:25:32

lz 牛,这样在实际工作中的体会很有实际意义,远比一些纸上谈兵有实际意义.
system888net 发表于 2010-10-20 09:01

    这不是牛不牛的问题,这是常识,可是初学者却不一定有这样的常识.

时光是把杀猪刀 2022-09-19 07:34:29

对于其原因,我的电脑截图不知为什么出了问题,所以无法截图了.有兴趣的用modelsim仿真一下以下的电路,仔细对照一下波形图,再想想或许就明白了.

  1. `timescale 1ns/1ps
  2. module reset_module_test(
  3.                                 gpio,
  4.                                 clk,
  5.                                 rst,
  6.                                 io_out
  7.     );
  8. input gpio,clk,rst;
  9. output io_out;
  10. parameter REG_WILDTH=6;
  11. reg io_out;
  12. reg [REG_WILDTH-1:0]gpio_reg;
  13. wire negedge_gpio, posedge_gpio;
  14. assign negedge_gpio = (&(gpio_reg[REG_WILDTH-1:REG_WILDTH/2])) & (!(|(gpio_reg[REG_WILDTH/2-1:0])));
  15. assign posedge_gpio = (!(|(gpio_reg[REG_WILDTH-1:REG_WILDTH/2]))) &  (&(gpio_reg[REG_WILDTH/2-1:0]));
  16. always@(posedge rst or posedge clk)
  17. if(rst)
  18.   gpio_reg <= 0;
  19. else
  20.         gpio_reg <= {gpio_reg[REG_WILDTH-2:0], gpio};
  21.        
  22. always@(posedge rst or posedge clk)
  23. if(rst)
  24.   io_out <= 1'b0;
  25. else
  26.   begin
  27.         if(negedge_gpio)
  28.                 io_out <= 1'b0;
  29.         else if(posedge_gpio)
  30.                 io_out <= 1'b1;
  31.   end
  32. endmodule
  33. module testbench
  34.   ();
  35.   reg clk,gpio,rst;
  36.   wire io_out;
  37.   reset_module_test reset_module_inst(
  38.                                 gpio,
  39.                                 clk,
  40.                                 rst,
  41.                                 io_out
  42.     );
  43.     initial
  44.     forever
  45.     begin
  46.     clk=0;
  47.     #2.5;
  48.     clk=1;
  49.     #2.5;
  50.     end
  51.    
  52.     initial
  53.       begin
  54.         rst=0;
  55.         #7;
  56.         rst=1;
  57.         #20;
  58.         rst=0;
  59.       end
  60.       
  61.     initial
  62.       begin
  63.         gpio = 1;
  64.         #1000;
  65.         gpio=0;
  66.         #100;
  67.         gpio=1;
  68.         #2000;
  69.         gpio=0;
  70.         #99;
  71.         gpio=1;
  72.         #4000;
  73.         gpio=0;
  74.         #12;
  75.         gpio=1;
  76.         #4000;
  77.         gpio=0;
  78.         #5;
  79.         gpio=1;
  80.         #2;
  81.         gpio=0;
  82.         #7;
  83.         gpio=1;
  84.         #6;
  85.         gpio=0;
  86.         #197;
  87.         gpio=1;
  88.         #5000;
  89.         $display("OK!");
  90.         $stop();
  91.         end
  92. endmodule

复制代码

慵挽 2022-09-19 06:17:49

lz 牛,这样在实际工作中的体会很有实际意义,远比一些纸上谈兵有实际意义.

天邊彩虹 2022-09-19 04:51:05

至于“用一个外部可能有毛刺的信号来作为组合输出,很危险”这一点,请相信我,我有过惨痛的教训。

乖乖 2022-09-18 14:55:56

本帖最后由 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
基本成了

怂人 2022-09-16 23:10:29

全部用内部寄存器来组合输出应该是比较好的选择。
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

花开半夏魅人心 2022-09-15 02:00:17

于是怎么办呢?我们还是要用到系统时钟,缓存一道试下,在上沿处生成单脉宽的一个信号。
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

似乎看起来很好了,但其实也只是五十笑百,利用一个外部可能有毛刺的信号来作为组合输出,很危险,出现真正意思上的上沿(并非毛刺)的时候,其附近如果有毛刺,那么就有抓不到的危险。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文