Verilog抠细节系列- -2(pulse变长)

这次想通过一个例子来带出一个思路,那就是实现一个同样的结果有很多种方法,我们要多花些脑筋选最安全的方法。
这次用一个pulse变长的例子吧。
相信很多人做设计的时候,会遇到说要求把一个pulse变长。
比如说一个clock长度的pulse,要变成2个,或3个,或4个,或N个clk长度。
如果要变得比较长,比如10几个或成百上千个clock,一般都会用计数器,我们这里先不讨论。
现在说最简单的,比如说1clk的pulse要变成3个clk长度吧。

看到这个要求,很多朋友就会说,超简单的,把这个pulse延迟3个or一下不就OK啦。
就象下面:

clk:  __|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|
pul1: _______|""""""|________________
pul2: ___________|""""""|________________
pul3: _______________|""""""|________________
pulse: ______|""""""""""""""""""""|________________

verilog:

always @(negedge clk or negedge rstb)
  if (~rstb)   pul2 <= 0;
  else pul2 <= pul1;

always @(negedge clk or negedge rstb)
  if (~rstb)   pul3 <= 0;
  else pul3 <= pul2;

wire pulse = pul1 | pul2 | pul3;

大家是不是也是这样做的呢?这样来延长pulse,是不是真的就是方便又简洁的好做法呢?
我也来说两句 查看全部回复

最新回复

  • windzjy (2008-7-21 17:35:20)

    除了计数,上升延延迟,还有其他什么好的方法呢?
  • windzjy (2008-7-21 17:40:10)

    刚才沙发的回复怎么删除了呢?
  • qingchuyu (2008-7-21 17:50:48)

    hah
    i think this is easy for others ,
    so there is no sense to exist.
    i can't type Chinese now,i'm very sorry.
  • leolf (2008-7-21 18:09:20)

    刚才有朋友回复了。说是会产生glitch。没错! 就是讨厌的“毛刺”,又出现了。大致原因如下波形:
    clk:  __|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|
    pul1: _______|""""""|________________
    pul2: ____________|""""|________________
    pul3: ________________|""""|________________
    pulse: ______|"""""""|"""""|""""""|________________

    因为register的反应延迟时间,所以这样产生的pulse理论上是会有glitch产生的。
    所以,这种做法其实并不是最好的。
    刚才有朋友也说了用计数器,不过如果2,3个clk的pulse也用计数器,就有点弄得复杂了。
    其实我们同样可以使用register来延迟,但是对信号做一点小小的改变,效果就不同了。

    New Verilog:

    always @(negedge clk or negedge rstb)
      if (~rstb)  pul2 <= 0;
      else if (pul1 == 1) pul2 <= 1;

    always @(negedge clk or negedge rstb)
      if (~rstb)  pul3 <= 0;
      else if (pul2 == 1) pul3 <= 1;

    always @(negedge clk or negedge rstb)
      if (~rstb)  pul4 <= 0;
      else if (pul3 == 1) pul4 <= 1;

    always @(negedge clk or negedge rstb)
      if (~rstb)  pul5b <= 1;
      else if (pul4 == 1) pul5b <= 0;

    wire pulse = pul2 & pul5b;

    从上面这个波形产生的pulse,理论上就会比较少一些glitch, 这里和上一个波形有一个clk的差别。
    是因为我比较懒,不想打pulse的上升沿触发,大家知道大概的意思即可。波形如下。

    clk:  __|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|
    pul1: _______|""""""|________________
    pul2: ___________|"""""""""""""""""""""""""""""""""""""""
    pul3: _______________|"""""""""""""""""""""""""""""""""
    pul4: ___________________|"""""""""""""""""""""""""""""""""
    pul5b: """""""""""""""""""""""""""""""""""|_________________
    pulse: __________|"""""""""""""""""""|________________


    当然,延长pulse应该还有其它方法,各位朋友可以把自己认为好的方法贡献出来给大家分享。
    今天到这里,要专心干活了。
  • qingchuyu (2008-7-21 18:16:06)

    you are a warmhearted man
    i like you
    hah
    thanks for sharing these experience
  • hover_edacn (2008-7-21 18:20:17)

    老大,你的code有问题啊:只能拓展一个pulse!
    另外,对于同步设计来说,glitch不是一个严重问题。
  • leolf (2008-7-21 18:27:35)

    QUOTE:

    原帖由 hover_edacn 于 2008-7-21 18:20 发表
    老大,你的code有问题啊:只能拓展一个pulse!
    另外,对于同步设计来说,glitch不是一个严重问题。
    哪出问题了?
    对于glitch,没有总比有的好嘛。
  • leolf (2008-7-21 18:28:57)

    QUOTE:

    原帖由 qingchuyu 于 2008-7-21 18:16 发表
    you are a warmhearted man
    i like you
    hah
    thanks for sharing these experience
    Thanks!
    You are obvious experience on these.
    Hope can learn more from you.
  • hover_edacn (2008-7-21 18:31:04)

    请画出第二个pulse来了之后的timing。
  • windzjy (2008-7-21 18:32:40)

    clk:  __|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|
    pul1: _______|""""""|________________
    pul2: ____________|""""|________________
    pul3: ________________|""""|________________
    pul4:___________________|''''''''|______________
    pulse: __________|"""""""""""""'''''''''|_____________
    用pul1和pul4做使能产生pulse
  • hymans0811 (2008-7-21 18:33:38)

    采用置1清0的方式,就不会有什么毛刺啊
  • leolf (2008-7-21 19:13:20)

    QUOTE:

    原帖由 hover_edacn 于 2008-7-21 18:31 发表
    请画出第二个pulse来了之后的timing。
    明白你的意思了。
    这种做法的确有一个缺点,就是没有rstb的话,只能扩展一个pulse。
    如果你要第二个pulse,就做得点手脚在第二个pulse来之前rstb吧。
  • xishuai (2008-7-21 19:51:26)

    完全可以用移位寄存器来实现嘛!
  • x512775199 (2008-7-21 21:18:12)

    呵呵 好好干活 leolf
  • hover_edacn (2008-7-22 10:22:08)

    呵呵,我说过在同步设计中毛刺是可以接受的。请问你的异步reset是外部引脚施加的,还是内部逻辑产生的,我相信是后者。那么你为了避免一个事实上可以接受的毛刺,而引入一个绝对无法接受的异步reset!
    在同步设计中,信号的毛刺除了会增大动态功耗之外,并不会影响芯片正常工作。而且组合逻辑超过一定级数,毛刺是无法避免的。既然无法避免,索性不去考虑,按coding style的要求来设计就可以了。
  • wanynal (2008-7-22 11:26:41)

    路过 学习
  • carsbus (2008-7-22 12:29:06)

    New Verilog:(5个DFF,无毛刺)

    wire pul5b;
    assign pulse = pul5b;
    always @(negedge clk or negedge rstb)
      if (~rstb)  pul2 <= 0;
      else if (pul1 == 1) pul2 <= 1;
      else if (pul5b == 0) pul2 <= 0;

    always @(negedge clk or negedge rstb)
      if (~rstb)  pul3 <= 0;
      else if (pul2 == 1) pul3 <= 1;
    else if (pul5b == 0) pul3 <= 0;

    always @(negedge clk or negedge rstb)
      if (~rstb)  pul4 <= 0;
      else if (pul3 == 1) pul4 <= 1;
    else if (pul5b == 0) pul4 <= 0;

    always @(negedge clk or negedge rstb)
      if (~rstb)  pul5b <= 1;
    else if (pul1 == 1) pul5b <= 1;  
    else if (pul4 == 1) pul5b <= 0;



    或者:用4个dff,无毛刺。
    wire pulse;
    reg pul1, pul2;
    reg [1:0] pul_counter;
    assign pulse = pul2;
    always @ (negedge clk or negedge rst_n)
    if (~rst_n) pul_counter[1:0] <= 2'b00;
    else if (pul1 == 1'b1) pul_counter[1:0] <= 2'b01;
    else if (pul2 == 1'b1) pul_counter[1:0] <= pul_counter[1:0] + 1;
    else if (pul1 == 1'b0 && pul2 == 1'b0) pul_counter[1:0] <= 2'b00;

    always @ (negedge clk or negedge rst_n)
    if (~rst_n) pul2 <= 1'b0;
    else if (pul1 == 1'b1) pul2 <= 1'b1;
    else if (pul_counter[1:0] == 2'b10) pul2 <= 1'b0;
  • ccj507 (2008-7-22 13:48:41)

    楼主,有个问题,你说用计数器来延长pulse对于只需要延长2,3个clk cycle的case来讲,有点浪费,但事实上, 我认为你上面的做法更浪费一些~~~3个clk, 假若用计数器只要2个DFF,再加1个2bit的自加1逻辑, 你的方法用了4个DFF,而且,还有需要延迟一个pulse之前,要rst一次...我个人认为你是将问题复杂化了~~当然,你的方法是一种不错的思路,或许其他case,你的方法会是比较好的solution. Anyway,分享感谢你的分享~~
  • x512775199 (2008-7-22 22:21:01)

    怎么leolf不来了。。。
  • gohigh008 (2008-7-23 15:25:25)

    看大家讨论,受益.以下是我自己写的一些东西,其中WIDTH和LONG两参数根据设计需要取不同值.希望和大家讨论:


    parameter    WIDTH = 8;      
    parameter    LONG  = 22;   // 1 < LONG < 256

    reg [(`WIDTH-1):0]    cnt;
    reg                   pulse;

    always @ (negedge clk or negedge rstb) begin
           if (~rstb) begin
                cnt <= {(`WIDTH){1'b0}};
           end
           else if (pul1==1'b1) begin
                cnt <= {(`WIDTH){1'b0}};            
           end
           else if (cnt==`LONG) begin
                cnt <= cnt;
           end
           else begin
                cnt <= cnt + 1'b1;
           end
          
    end

    always @ (negedge clk or negedge rstb) begin
           if (~rstb) begin
                pulse <= 1'b0;
           end
           else if (pul1==1'b1) begin
                pulse <= 1'b1;
           end
           else if (cnt==(`LONG-1)) begin
                pulse <= 1'b0;            
           end
          
    end