FPGA での非同期信号の扱い方と
Vivado によるサポート
marsee
2
非同期信号とは?
●
非同期信号
– 回路の使用しているクロックに同期していない信号
●
非同期信号の種類
– 完全に非同期な信号
●
スイッチ入力(人間がスイッチを押す)
– 異なるクロックで動作する回路の出力を入力する
●
PS2
●
I2C
●
SPI
●
非同期信号を FPGA に入力する場合に問題が発生する
3
非同期信号を入力する場合
●
回路のクロックに同期していない入力
– 入力信号の変化する部分にクロックの立ち上がりが来て
しまう場合もある
クロック
入力
クロック
入力
たぶん OK
問題発生 !!!
4
メタステーブル状態
●
フリップフロップ (FF) にはセットアップ時間とホール
ド時間がある
●
それらを満たせないと不安定な出力が出る場合がある
図は FPGA 2.0 、コラム : 非同期クロック と 検証手法 -2 から引用
http://www.altima.jp/products/sofware/mentor/fv/column/cdc-2.html
組み合わせ回路
5
メタステーブルの対処方法
●
FF を 2 段以上入れる
●
●
●
私の対処方法
– Vivado IPI で Synchronizer IP を自分で作成
図は FPGA 2.0 、コラム : 非同期クロック と 検証手法 -3 から引用
http://www.altima.jp/products/sofware/mentor/fv/column/cdc-3.html
6
Synchronizer IP の設定画面
●
Bit Widths で
FF のビット幅を
設定
●
Number Of
Stages で FF を
何段接続するか
を設定
7
synchronizer.v
module Synchronizer #(
parameter integer NUMBER_OF_STAGES = 2,
parameter integer BIT_WIDTHS = 1
)(
input wire clk,
input wire [BIT_WIDTHS-1:0] inp,
output wire [BIT_WIDTHS-1:0] outp
);
integer i;
reg [BIT_WIDTHS-1:0] f[NUMBER_OF_STAGES-1:0];
always @(posedge clk) begin : proc_gen_f
for (i=0; i<=NUMBER_OF_STAGES-1; i=i+1) begin
if (i==0) begin
f[i] <= inp;
end else begin
f[i] <= f[i-1];
end
end
end
assign outp = f[NUMBER_OF_STAGES-1];
endmodule
8
Synchronizer IP の使用場所
9
FPGA 内部でのクロックの数
●
畳み込みニューラルネットワークによる白線間走行ミ
ニ・ロボットカーのクロック数 ー 5 個
– AXI4 インターフェース・クロック 100MHz
– カメラ用出力クロック 72MHz
– カメラ用入力クロック 36MHz
– ディスプレイ・コントローラ用クロック( SVGA ) 40MHz
– ディスプレイ・コントローラ用クロック( XGA ) 65MHz
10
クロックの異なる回路間での信号の受け渡し
●
入力に 2 段以上の FF を付ける
●
入力は少なくともクロックの 3 倍を超える長さが良い
クロック
信号
全くダメ
クロック
信号
もう一声
大丈夫!
クロック
11
異なるクロック間でのデータは?
●
低速で良いのならばハンドシェークで
– VALID, ACK
– データを出力と同時に VALID
– データを受け取ったら ACK を返す
– ACK は落ちるのも見る
VALID
DATA
ACK
DATA0
12
異なるクロック間でのデータは? 2
●
非同期 FIFO
– 入力データと出力データのクロックが異なる FIFO
– Xilinx の FIFO Generator
13
同期 FIFO の構造
FPGA の部屋 「同期 FIFO と非同期 FIFO 」
http://marsee101.blog19.fc2.com/blog-entry-1085.html
14
非同期 FIFO の構造
図は Advanced FPGA Design: Architecture,
Implementation, and Optimization, 96 ペー
ジ、 Figure 6.14 Simplified asynchronous
FIFO を参考にした
FPGA の部屋 「同期 FIFO と非同期 FIFO 」
http://marsee101.blog19.fc2.com/blog-entr
y-1085.html
15
自作のカメラ・インターフェース IP での
非同期信号の取り扱い
●
last_pixel_4_line
は行のピクセル最
後のデータ
●
first_pixel はフ
レームの最初の
データ
●
制御信号もデータ
と一緒に非同期
FIFO へ入力
// pixel FIFO をインスタンスする
pixel_fifo pfifo (
.rst(areset), // input rst
.wr_clk(pclk), // input wr_clk
.rd_clk(aclk), // input rd_clk
.din({last_pixel_4_line, first_pixel, rgb565_1d}), //
input [33 : 0] din
.wr_en(line_v_1d_odd_2d), // input wr_en
.rd_en(pfifo_rd_en), // input rd_en
.dout(pfifo_dout), // output [33 : 0] dout
.full(pfifo_full), // output full
.almost_full(pfifo_almost_full), // output
almost_full
.overflow(pfifo_overflow), // output overflow
.empty(pfifo_empty), // output empty
.almost_empty(pfifo_almost_empty), // output
almost_empty
.underflow(pfifo_underflow), // output underflow
.rd_data_count(pfifo_rd_data_count) // output [9 :
0] rd_data_count
);
16
ビットマップ・ディスプレイ・コントローラ IP での
非同期信号の取り扱い
●
vsync_node
は clk_disp で
出力されてい
る
●
2 段の FF をか
まして
vsyncx_rise_
pulse を出力
// vsync を clk_axi で同期化
always @(posedge clk_axi) begin
if (reset_axi) begin
vsync_axi <= 1'b0;
vsync_axi_b1 <= 1'b0;
vsync_axi_1d <= 1'b0;
end else begin
vsync_axi_b1 <= ~vsyncx_node;
vsync_axi <= vsync_axi_b1;
vsync_axi_1d <= vsync_axi;
end
end
// vsyncx_rise_pulse の処理。 vsyncx の立ち上がり時に 1 パルス出力する
always @(posedge clk_axi) begin
if (reset_axi)
vsyncx_rise_pulse <= 1'b0;
else begin
if (vsync_axi==1'b0 && vsync_axi_1d==1'b1)
vsyncx_rise_pulse <= 1'b1;
else
vsyncx_rise_pulse <= 1'b0;
end
end
17
Vivado の機能( Clock Domain Crossing )
●
Vivado の Flow Navigator から Open Implemented
Design を開いて、 Tools メニュー -> Timing ->
Report CDC... を選択する
●
Report CDC ダイアログの From と To に解析するク
ロック・ドメインを指定しして OK ボタンをクリック
●
デモします
●
FPGA の部屋「 Vivado の Implemented Design で
Report CDC を確認する」参照
– http://marsee101.blog19.fc2.com/blog-entry-3337.
html
18
まとめ(最後はですます調に変調します)
●
非同期信号を受ける場合は必ず 2 段以上の FF で受けて
から使いましょう
●
クロックが異なる回路とやり取りをするときは十分に注
意しましょう
●
データはなるべく非同期 FIFO で渡しましょう
●
Vivado の Implemented Design には Report CDC と
いうクロック載せ替えのためのレポート機能があります
19
参考文献
●
【 FPGA 】内部生成リセットやリセットの混合使用【リ
セット回路】
– http://fpgainfo.blog.fc2.com/blog-entry-92.html
●
コラム : 非同期クロック と 検証手法 -1
– http://www.altima.jp/products/software/mentor/fv
/column/cdc-1.html
●
非同期信号を扱うための危うい Verilog ライブラリ
– http://dora.bk.tsukuba.ac.jp/~takeuchi/?cmd=read
&page=%E9%9B%BB%E6%B0%97%E5%9B%9E%E8%B7%AF%2FHDL
%2F%E9%9D%9E%E5%90%8C%E6%9C%9F%E4%BF%A1%E5%8F%B7
%E3%82%92%E6%89%B1%E3%81%86%E3%81%9F%E3%82%81%E3
%81%AE%E5%8D%B1%E3%81%86%E3%81%84Verilog%E3%83%A

Fpgaでの非同期信号の扱い方とvivadoによるサポート(公開用)