非同期信号を扱うための危ういVerilogライブラリ のバックアップ(No.1)

更新


公開メモ

※ 以下は練習のために書いてみたものです。
しっかりとしたテストを経ていないので、鵜呑みにしないで下さい。
個人的なメモになってしまいすみません。

クロックドメイン間で安全に信号線(バス)を受け渡す

非同期 Fifo のカウンタを受け渡す用途などに汎用的に使いたくて作った回路です。

それぞれ2段の FF を介して request / acknowledgement をやりとりして、 データを安全に受け渡すことを試みています。

インスタンシエーション時にパラメータでバス幅を変えられるので、 非常に一般的に使えると思います。(正しく動けば・・・)

[添付]

LANG:verilog
module synchronize #(
    parameter DATA_BITS = 8
) (
    input rst,
    input iclk,
    input [DATA_BITS-1:0] idata,
    input oclk,
    output reg [DATA_BITS-1:0] odata
);

    (* TIG="TRUE" *) reg [DATA_BITS-1:0] temp;
    (* TIG="TRUE" *) reg req;
    (* TIG="TRUE" *) reg ack;

    reg ack1, ack2;
    always @(posedge oclk)
        if (rst) begin
            req <= 1;
            ack1 <= 0;
            ack2 <= 0;
            odata <= temp;
        end else begin
            if ( req == ack2 ) begin
                req <= !req;
                odata <= temp;  // interclock signal "temp"
            end
            ack1 <= ack;        // interclock signal "ack"
            ack2 <= ack1;
        end
        
    reg req1, req2;
    always @(posedge iclk)
        if (rst) begin
            ack <= 0;
            req1 <= 0;
            req2 <= 0;
            temp <= idata;
        end else begin 
            if ( req2 != ack ) begin
                ack <= !ack;
                temp <= idata;
            end
            req1 <= req;        // interclock signal "req"
            req2 <= req1;
        end
        
endmodule

Counter: 164168 (from 2010/06/03), today: 1, yesterday: 0