iT邦幫忙

0

[verilog] always裡面有兩個posedge

  • 分享至 

  • xImage

我的always裡面有兩個posedge訊號,CLK_LF(頻率較低)和CLK(頻率較高)
若是CLK_LF的正緣,則irq=1,若是CLK的正緣,則irq=0。程式碼如下

always @( posedge CLK or posedge CLK_LF ) begin
        if (CLK_LF) begin
            irq<=1;
        end
        else begin
            irq<=0;
        end
    end

但這樣實際上會有一個問題,當此時是CLK正緣來的時候會先執行if (CLK_LF)判斷是否為真,但這個情況下好像是看CLK_LF是否為邏輯1,而不是判斷CLK_LF是否為正緣,請問要如何寫出if (CLK_LF正緣)的verilog?

marlin12 iT邦研究生 5 級 ‧ 2019-12-28 22:45:16 檢舉
如果有比CLK更高頻率的時脈,可以用它來對CLK和CLK_LF取樣,便可以找出它們的正緣在那裏。
wrxue iT邦好手 1 級 ‧ 2019-12-28 23:08:19 檢舉
您好,CLK是最高頻的時脈。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
marlin12
iT邦研究生 5 級 ‧ 2019-12-29 13:51:28
最佳解答

根據取樣定理, 如果CLK頻率是CLK_LF頻率的两倍或以上,便可以對CLK_LF進行取樣。
因此,在always區塊裏面,不論觸發是來自CLK或者CLK_LF,都可以對CLK_LF進行取樣(只要符合[取樣定理]便可以)。
當下次always被觸發的時候,便可用之前CLK_LF的取樣,比對觸發時CLK_LF的狀態,判斷觸發是否來自CLK_LF正緣。

[備註]當CLK正緣和CLK_LF正緣同時出現時,IRQ會被設定為1。

在線測試

[Module]

module block(input clk_lf, input clk, output irq);
    reg irq = 0;
    reg clk_lf_r = 0;  // 記錄clk_lf狀態

    always @ (posedge clk or posedge clk_lf) begin
        if( clk_lf & ~clk_lf_r ) begin  // clk_lf正緣
            irq <= 1;
        end
        else begin  // clk正緣
            irq <= 0;
        end
        
        clk_lf_r <= clk_lf;  // 對clk_lf取樣
    end
endmodule

[TestBench]

module main;
  reg clk, clk_lf;
  wire irq;

  block blk1(clk_lf, clk, irq);

  integer x;

  initial begin
    $monitor("t=%03d clk=%1d clk_lf=%1d, irq=%1d \n", $time, clk, clk_lf, irq );

    for( x = 0; x < 5; x = x + 1 ) begin
      clk_lf <= 0;
      #30
      clk_lf <= 1;
      #25
      clk_lf <= 0;
    end

    $finish;
  end

  initial begin
    forever begin
      clk <= 0;
      #10
      clk <= 1;
      #10
      clk <= 0;
    end
  end
endmodule
wrxue iT邦好手 1 級 ‧ 2019-12-30 09:14:18 檢舉

太棒了,感謝您!

marlin12 iT邦研究生 5 級 ‧ 2019-12-30 18:56:55 檢舉

不用客氣!

我要發表回答

立即登入回答