01signal.com

エレクトロニクス悪魔払い: FPGA がときおり取り憑かれたように振る舞う理由

おかしな挙動が見られたら

FPGA は概して極めて信頼性の高い部品ですが、どんなテクノロジーもそうであるように、誤った使い方をすればうまく動作してくれません。

残念ながら、FPGA 設計ツールは人間がミスをしないように導いてくれるわけではなく、そのせいで信頼性の低い予測不能な結果に陥ることがあまりにも多いのです。もう少し具体的にいうと、FPGA ツールが安定した動作を保証してくれるのは、一定の設計作法が守られている場合だけです。しかも、そこで前提とされているのは「私たち人間は自分のやっていることを理解している」ということです。ソースコードにエラーがあれば実行コードを生成しないソフトウェアコンパイラとは違い、FPGA ツールはこう言うだけです。「どうぞ、これがあなたのビットストリーム(bitstream)です。よければ試してみてください。そうそう、警告が 200 個ほど出ています。警告 #143 の意味が理解できるなら、直すべき重大な問題があることも理解できるはずです」と。

FPGA に携わる人が、電子回路そのものが何か魔法の力に取り憑かれたと感じ、何もかも不合理に思えることは珍しくありません。まったく無関係な変更によって問題が現れたり消えたりして、合理的な説明が見当たらないこともあります。きちんとした教育を受けた技術者でも、こうした奇妙な挙動を説明しようとして、FPGA について非合理な説を信じてしまうことがよくあります。

これが「Black Magic Mode(黒魔術モード)」です。分別ある技術者が、自分の問題には合理的な説明があると信じるのをやめ、経験に基づいた対処法を探し始めたときに、このモードに入ります。FPGA が冷えているときはすべてうまく動く? よし、巨大なヒートシンクを取り付けよう。問題が出るのは一部のボードだけ? OK、全ボードをテストして、動かないものは捨てよう。そんな調子です。

どんな症状になるのか

技術者を非合理な考え方に追い込みかねない問題の一部を挙げてみます。それはいつも「すべてはうまく動いている。ただし、こんなとき以外は」という形で現れます。

こうなると、電子回路そのものに欠陥があり、データシートどおりの性能が出ていないのだ、と信じがちになります。巨大企業が欠陥部品を出荷している、という陰謀論も珍しくありません。

つまり、これはただのバグではありません。実際、どんなバグでも人を狂わせることはありますが、バグにはそれなりの再現性があるものです。エアコンのせいで現れたり消えたりするはずがありません。ソフトウェア技術者がバグを PC 本体のせいにするのは聞いたことがありません(実際にはごくまれにそういうケースもありますが)。一方、FPGA 設計の誤りは、間違いなくハードウェアレベルの誤動作を引き起こします。そこから世の中すべてを責め始めるまでには、ほんのわずかな距離しかありません。

理屈に合った説明はある。本当に。

しかも手の届くところにあります。簡単だとは限りませんが。

この分野でフリーランスとして長く働き、こういった状況をときどき解決してきた私の言葉を信じてください。ごくまれなケースを除けば、FPGA は正常です。問題はおそらくビットストリームの中にあります。

悪い知らせとしては、FPGA 設計の中に欠陥が一つ以上あることは珍しくなく、それらの欠陥がいま見えている問題の原因になっている可能性があります。つまり、直すべきことがたくさんあるかもしれないのです。「ほぼ動いている」FPGA 設計の修正を頼まれ、それが「この小さな問題」ならすぐ直るだろうという非現実的な期待に直面したことは、何度もあります。設計を安定させる作業は、目に見える進展がないまま多くの労力を必要とすることがよくあります。

いずれにせよ、やるしかありません。このページでは、電子回路に幽霊がいるように見える原因を列挙しながら、合理的な考え方を取り戻す手助けをしたいと思います。

もちろん、そもそもこうした状況を避けるのが最善です。別のページにまとめた Golden Rules を守ることから始めるのが良いでしょう。

なぜおかしなことになるのか

手短に言えば、FPGA 設計のどこかがおかしいのです。そして、その場合には原理的に二つの可能性があります。比較的幸運なのは、FPGA が本来やるべきことに対して、目に見える安定した誤動作が起きるケースです。これはソフトウェアのバグのようなものです。見つけて、直して、直ったことを確認して、終わり。

あまり幸運でない可能性は、FPGA は動いてはいるものの、それがほとんど偶然の一致だというケースです。そのため、何かの条件が変わると、FPGA が突然正しく動かなくなり、また動くようになることもあります。では、なぜこんなことが起きるのでしょうか?

ここが要点です。FPGA は電子部品ですから、製造時にどうしても不正確さがつきまといます。さらに重要なのは、シリコンの温度が変わると、トランジスタが状態を変える速度も変わることです。信号がロジックファブリック上を伝わる速度についても同様です。電源電圧の変化も、FPGA 内部で物事がどれだけ速く起こるかに影響します。

したがって、FPGA が少し暖かくなったり冷たくなったりすると、クロックに対して信号がフリップフロップにわずかに遅れて到着したり、わずかに早く到着したりすることがあります。それだけで、そのフリップフロップが取り込むべきだった信号を取り損ねたり、ふだんは取り損ねる信号を取り込んでしまったりします。シリコンが局所的に発熱しても同じことが起きます。チップ上で隣接する(おそらく無関係な)ロジックの活動量が増減すると、そこが熱くなるからです。

同様に、FPGA にも製造ばらつきがあります。工場から出荷される FPGA はすべて、仕様を満たすことを確認するテストに合格していますが、FPGA によってはほかよりもシリコンが速い場合があります。これが、不適切に作られたロジック設計がある FPGA ではうまく動き、別の FPGA では動かない理由です。

こうしたランダムなパラメータはすべて、ロジックファブリック上の小さな部品がいつ状態を変えるかに影響します。そして、そのタイミングの違いが、完璧に動くか大惨事になるかの違いを生みます。つまり、製造ばらつき、温度、電圧のわずかなずれが、目に見える違いとなって現れるのです。

では、FPGA はどうやって信頼性を確保しているのでしょうか? FPGA 設計が正しく行われていれば、FPGA 設計ツールが、定義されたとおりに常にすべてが機能することを保証します。もう少し正確に言うと、製造テストに合格し、データシートの要件に従って使われる FPGA であれば、どれでもすべてが機能することを保証します。つまり、周囲温度を必要な範囲内に保ち(必要に応じて冷却し)、FPGA のピンに正しい電圧を供給すればよいのです。

しかし、FPGA 設計に求められる作法を守らなければ、ツールも正しい動作を保証してくれません。つまり、影響を与えるはずのないパラメータが決定的に重要になり、まったく関係ないはずの事柄に左右されて、ボード全体が動いたり止まったりするのです。おかしさには際限がありません。

繰り返しになってしまいますが、いくつか例を挙げます。

これは何度でも繰り返す価値があります。FPGA 設計が正しく行われていれば、こうしたことは一切起こりません。少なくとも、ごくまれにしか起こりません。データシートを読んで守り、FPGA も正しく使えば、電子回路がどれほど信頼できるものなのか、気づいている人はほとんどいません。

ただ、この説教は、このページを読んでいるあなたには少し遅すぎるかもしれませんね。問題はすでに起きているのですから。そこで、自分の経験に基づいて、まるで幽霊に取り憑かれたかのような FPGA によくある原因をリストにしました。もしあなたがそんな問題に直面しているなら、その原因はこの中のどれかである可能性が高いです。

理由その1: タイミング

FPGA の安定動作は、ツールが、あなたが与えた タイミング制約(timing constraints) を達成することで、おおむね保証されています。これは、あなたとツールとの間の取り決めです。あなたがタイミング要件を正確に表現し、ツールは、FPGA が許容温度・電圧の範囲内で動作する限り、使うどの FPGA でもその要件が達成されることを保証する、という取り決めです。

タイミング制約が単一の制約、つまり リファレンスクロックの周波数 だけ、ということは珍しくありません。それで十分なこともあります。しかし、その行をほかの設計からコピーしただけで、「動いているからいいや」と思っているなら、見直す十分な理由があります。

実際には、これは一般にタイミング設計を正しく行うということです。そして、それは最も経験豊富な FPGA 設計者にとっても簡単な作業ではありません。具体的には、設計内のすべての信号パス(path)について、その終端にあるフリップフロップが常に正しく信号を受け取れることを保証する制約がかかっていることを確認する、ということです(制約が不要なパスは除きます)。

まず確認すべきこと: 設計はタイミング制約を達成しているでしょうか? これは本当に基本的なことですが、ほとんどの FPGA ツールは制約を満たしていなくてもビットストリームを生成してしまうため、FPGA 初心者はこの単純なミスに陥ることがあります。

次に、タイミング制約そのものを見直してください。こうした点検については 別のページ で説明していますが、手短に言えば次のとおりです。タイミング制約の意味を正確に理解していますか? その意味は、本来あるべきとおりですか? 特定のパスだけをフィルタ条件で制約する「選択的なタイミング制約」がある場合、それが本当に正しいパスに適用されていますか?

そして、タイミングレポートも注意深く読むべきです。繰り返しになりますが、この別ページ で詳しく説明しています。

もう一つ確認すべきは、クロックドメイン交差(clock domain crossing) です。あるクロックドメイン(clock domain)から別のクロックドメインへ、安全でない方法で渡っている信号はありませんか? これは、どのロジックがどのクロックに属しているかへの注意不足が原因で起こり得ます。クロックドメイン交差は、FPGA ツールが生成した FIFO だけで行っていますか? そうでないなら、その交差は正しく安全に行われていますか?

理由その2: 不適切なリセット

一見すると関係なさそうに思えるかもしれませんが、ロジックの初期状態が保証されていないと、Black Magic 的な挙動を引き起こす可能性は十分にあります。

ルールは単純です。リセットとロジックの起動時動作について真剣に考えていないなら、おそらく間違っています。

特に、次の例を考えてみてください。

   always @(posedge clk or negedge resetn)
     if (!resetn)
       the_reg <= 0;
     else
       the_reg <= [ ... ] ;

リセットに対する考え方が、このようなコードを書くこと、つまり @resetn が無効化(この例ではHigh に変化する)ときに何が起こるかを明示的に処理しない、というものなら、ぜひ このページ を見てください。

いずれにしても、リセットが必要な箇所にリセットがあり、それが正しく機能していることを確認するのは良い考えです。この点については、このテーマに関する 短いシリーズのページ で説明しています。

理由その3: クロック供給

クロックの品質は、デジタル設計でおそらく最も軽視されているテーマでしょう。「ハイとローを行ったり来たりしているな。よし、これをクロックにしよう」という感覚で使われることがよくあります。

FPGA ロジックに使うクロックは、安定していて、十分なジッタ(jitter)特性を備えていなければなりません。それと同じくらい重要なのは、FPGA へのクロックの物理的な接続が安定していて信頼できることです。

したがって、次のような記述では、

always @(posedge clk)

@clk として使われるものには、細心の注意を払わなければなりません。理想的には、そのクロックは専用のクロック生成部品(オシレータ)に由来し、安定していて低ジッタのクロックが保証されることです。一般に、この外部クロックはロジックに直接接続するよりも、PLL へのリファレンスクロックとして使う方が良いでしょう。たとえ PLL が周波数を変えない場合でも、これは当てはまります。

なぜなら、PLL を使えば PLL のロック検出出力を監視できるからです。PLL がロックしていない間、このクロックに依存するロジックをリセット状態に保持できます。そうすることで、リファレンスクロックに安定性の問題がある場合(特に電源投入直後)に問題が起きる可能性を大幅に減らせます。

PLL はトラブルメーカーと誤解されることがあります。ときどきロックを失うため、一見不要に見えるリセットが発生するからです。その結果、PLL を取り外して外部クロックを直接ロジックに接続すると、すべてがうまく動いているように見えるため、誤って「修正」してしまうことがあります。このような場合、リファレンスクロック側に問題がある可能性が高いです。PLL を取り外しても問題は解決せず、むしろ問題をロジックファブリックの中に押し込んで、Black Magic 状況を引き起こすかもしれません。

ここまでは専用オシレータ由来のクロックについて話してきましたが、これは本当に簡単なケースです。ほかの供給源になると事態は悪化します。プロセッサまたはそのペリフェラルが生成するクロックは、使うにしても慎重に扱う必要があります。そうしたクロックは、プロセッサの動作によって瞬間的に止まったり、時として不正な波形を出力したりすることがあります。これは、ソフトウェアが関連するハードウェアレジスタに書き込むことが原因で、その書き込みは無関係なタスクの一部かもしれません。こうした短いイベントは、オシロスコープでクロックを調べても見えないかもしれませんが、それでも奇妙な誤動作を引き起こします。

もう一つのよくある問題源は、ソースシンクロナスクロック(source synchronous clock) の扱いがまずいことです。つまり、外部コンポーネントがクロック信号と 1 本以上のデータ信号を供給し、そのデータがクロックに同期している場合です。通常、データ信号の値が変化するのは、クロックの立ち上がりエッジ(または立ち下がりエッジ)に合わせてだけです。

一般的でありながらかなり危険な方法は、ソースシンクロナスクロックを FPGA 内部の アプリケーションロジックに直接接続 することです。この方法の問題の一部は、ソースシンクロナスクロックは連続クロックとして使うことを想定されていないことが多く、瞬間的に止まったり、不正なパルスが発生したりする可能性があることです。

もう一つの可能性のある問題は、ソースシンクロナスインターフェースが物理コネクタを介して FPGA に接続されることが多いことです。たとえば、データ源がケーブルでメインボードに接続されたカメラの場合です。コネクタは通常信頼できますが、振動によって物理的接触が 1 ナノ秒失われるだけで、クロック信号に不正なパルスが発生するのに十分なことがあります。もちろんデータ信号でも同じことは起こり得ますが、特にデータ源がカメラの場合は、通常それほど重要ではありません。しかし、そうしたクロック信号をアプリケーションロジックに直接接続していると、1 ナノ秒のパルスが間違いなく大混乱を引き起こし得ます。

したがって、クロックとデータを伴うソースシンクロナスインターフェースの 最善の解決策 は、クロックもデータも通常の信号として扱うことです。つまり、ソースシンクロナスクロックとデータ信号の両方を、安定していて安全なはるかに高速なクロックで、フリップフロップを使ってサンプリング(sampling)します。できれば、I/O ピンに隣接する専用フリップフロップを使うのが良いでしょう。

ソースシンクロナスクロックが Low から High に変化すると、その信号をサンプリングしているフリップフロップの出力にも同様の変化が現れます。したがって、このフリップフロップの出力が Low から High に変わるという単純な事実によって、ソースシンクロナスクロックの立ち上がりエッジを同期ロジックで検出できます。このロジックはもちろん、より高速で安定したクロックに基づいています。このロジックがこうした立ち上がりエッジを検出すると、データを有効としてマークします。言い換えれば、データ入力の値を保持しているフリップフロップの出力が、有効なデータとしてマークされます。

この 01 信号サンプリング(01-signal sampling)方式の明らかな利点は、クロック信号に何が起ころうと、FPGA のロジックは安全なクロックに頼り続けられることです。ソースシンクロナスクロックがおかしくなった場合、エッジを検出するロジックが適切に対応するかどうかが鍵になります。

この技法が使えるのは、ソースシンクロナスクロックの周波数が比較的低い場合です(通常は 200〜300 MHz まで。FPGA の速度や DDR サンプリングを使うかどうかによります)。

より高速なソースの場合、好ましい解決策は、ソースのクロックを PLL に入力 し、その PLL の出力をアプリケーションロジックで使うことです。前述のように、PLL がロックしていないことを示している間は、ロジックをリセットすべきです。これは別の理由からも正しい解決策である可能性が高いです。先ほど示した 01 信号サンプリングを使うには周波数が高すぎる場合、正しいサンプリングを保証する唯一の方法は、クロックの位相シフトによってタイミングを見つけることである可能性が高いからです。つまり、サンプリングされた信号にエラーが検出されなくなるまで、ロジックがタイミングを自動調整します。この技法は、どうせ PLL を必要とします。

理由その4: RTL 設計のルール違反

シンセシス用の正しい Verilog コード(または VHDL)は、いくつかの厳格なルール、特に RTL(Register Transfer Level)パラダイムに従わなければなりません。その一つとして、何らかのメモリ的な要素(たとえばフリップフロップ)は、クロックエッジによってのみ値が変わります。唯一の例外は非同期リセット(asynchronous reset)ですが、それも 任意の信号でよいわけではありません。

シンセサイザ(synthesizer)がこれらのルールに違反する Verilog コードに遭遇すると、たいていは協力的に振る舞おうとして、シミュレーションと同じにならない可能性のあるロジックを生成します。あるいは、合成結果がほとんどの場合期待どおりに動作するものの、ランダムに失敗することがある、という可能性もあります。

たとえば、0 から 14 まで数えるカウンタの、次のような間違った設計を考えてみましょう。

reg [3:0] counter;
wire      reset_cnt;

assign reset_cnt = (counter == 15); // This is so wrong!

always @(posedge clk or posedge reset_cnt)
  if (reset_cnt)
    counter <= 0;
  else
    counter <= counter + 1;

恐ろしい間違いは、@reset_cnt を非同期リセットとして使っていることです。

まず、シミュレーションではこれがどのように動作するかを説明しましょう。@counter は @clk の立ち上がりエッジでカウントアップします。しかし @counter が値 15 に達すると、@reset_cnt が '1' に変わり、@counter を非同期的にゼロへリセットします。したがって @counter を @clk でサンプリングすると、期待どおり 0 から 14 の値を示します。

しかしハードウェアでは、これはうまくいかないかもしれません。問題は、@reset_cnt が @counter の組合せ論理(combinatorial logic)関数であることです。@counter の値が 7 から 8 に変わるとき、@reset_cnt を計算するロジックが @counter の値を一瞬 15 と見なす可能性があります。7 は二進数で 0111、8 は 1000 だからです。もし bit 3 から @reset_cnt を計算するロジックへの伝播遅延が最も短ければ、この信号は一瞬 '1' になるかもしれません。その結果、@counter はときには 0 から 14 まで数え、ときには 0 から 7 までしか数えません。どちらの動作になるかには、温度やそのほかの無関係な要因が影響することがあります。

ただし、この例がなぜ間違っているかについての説明は、大幅に簡略化されています。ツールは組合せ論理を最も独創的な方法で実装することができるため、クロックエッジの間には事実上何でも起こり得ます。ツールが保証するのは、宛先のフリップフロップのタイミング要件(セットアップ時間とホールド時間)に従って信号が安定していることだけです。

したがって、ロジック設計が RTL 設計のルールを厳密に守っていない限り、おかしなことは間違いなく起こり得ます。

理由その5: 温度と電源

これはそれほどよくあるトラブルの原因ではなく、確認も簡単です。それでも、温度と電源は奇妙な問題の根本原因になり得ます。

当然のことながら、シリコンの温度が許容範囲外にあると、正常な動作は何も保証されません。最もよくあるのは、熱設計の不足による過熱、あるいはほこりで目詰まりしたファンです。

電源については、さまざまな理由で誤った出力を出す可能性があります。オシロスコープで簡単に確認すれば、電圧が規定範囲内かどうかがわかることがよくあります。ただし、電圧は常にその範囲内に保たれている必要があります。平均電圧が正しいだけでは不十分で、スイッチング電源が常に発生させるノイズも、時折発生するスパイクも、リミットを超えてはなりません。

1 μs 以下のスパイクは無害に思えるかもしれませんが、FPGA 内部では数十から数百クロックサイクルに相当します。つまり、FPGA に誤った電圧が供給される、無視できない時間帯が生じます。できれば FPGA の近くにあるデカップリングコンデンサで電圧を測定し、実際に届いている電圧を確認してください。また、オシロスコープのトリガを電圧の上限と下限に設定し、通常の信号には反応せず、上下限を超えた場合にのみ反応することを確認してください。短いスパイクはオシロスコープの表示では気づきにくいですが、トリガなら捕まえられます。

電源の問題は、ボード設計のまずさが直接の原因であることがあります。多くの電源モジュールには最小電流という仕様があり、これが見落とされがちです。この最小電流を電源モジュールから引き出していないと、モジュールが不安定になり、仕様を満たさない電圧を出力したり、さらに悪い場合には時折発振したりすることがあります。

もう一つのよくある間違いは、電圧レギュレータが必要な場所にスイッチング電源を置くことです。特に、低ジッタ(jitter)のクロックオシレータの中には、非常にクリーンな入力電源を必要とするものがあります。もしそのようなオシレータにノイズの多い電源から給電すると、そのノイズがクロック出力のジッタとなって現れます。そのクロックをギガビットトランシーバ(PCIe、USB 3.x、光ファイバなど)が使っていると、信頼性の低いデータリンクになることがよくあります。

同様に、DDR メモリを設計に含む場合、リファレンス電圧用の電源が必要です。この電圧は、FPGA と DDR メモリの間の配線において '0' と '1' を区別する電圧しきい値として、FPGA と DDR メモリの両方で使われます。この電圧をスイッチング電源で生成していると、電源ノイズによって FPGA と DDR メモリ間でエラーのないデータ転送が難しくなったり、最悪の場合不可能になったりする可能性が高いです。

理由その6: 冗談でしょう?

Black Magic 状況の原因が、よくもまあそれでも動いていたものだ、と思えるような大きな欠陥であることがあります。たとえば、PCB 上の配線が関連する FPGA ピンから完全に切断されているのに、クロストークや寄生容量によって正しい信号が FPGA に届いてしまう場合です。

これは特にクロックで起こりがちです。クロックはボード上のあちこちに配線されることが多く、周期信号であるために、正常に見えるほど十分な品質で FPGA に届く可能性が高まるからです。

ぜひオシロスコープを使って、FPGA にできるだけ近い場所で全てのクロックを確認してください。クロックに AC カップリングコンデンサがあるなら、そこは良いチェックポイントです。特に、コンデンサが実装されていないことを発見できるかもしれませんから。

理由その7: 単なるバグ

もう少し正確に言うと、そもそも設計が「動くように」なっていなかった、ということです。誰も腰を据えて、ロジックが確実に意図どおり動作する仕組みを考え出したことがないのです。代わりに、シミュレーションとハードウェアを部分的に使った試行錯誤で、コードが少しずつ書かれていきました。その過程は、とりあえず動いているように見えた時点で終了します。しかしコードを見ると、よくそれで動いたものだと思えるほどです。小さな問題を直すために何度もパッチが当てられ、何が行われているのかを追うことはおろか、変更を加えることすら不可能な状態になっています。

この理由を最後にしたのは、これは本当の Black Magic 的な挙動ではないからです。これはただの非常に厄介なバグです。それでも、FPGA プロジェクトが行き詰まる最も一般的な理由はこれです。

それでも FPGA のせいだと思うなら

ときには、あなたのせいではないこともあります。FPGA 自身やベンダのソフトウェアにバグがあるかもしれません。これは、人々が FPGA ベンダを責めがちな頻度よりはるかに少ないですが、まれに実際にそういうケースがあります。

ほかの誰かを責めたくなるのが自然な心理です。自分を助けるためにも、次の 2 つのうちのどちらか、あるいは両方がない限り、悪魔払いのセッションを「FPGA のせい」で締めくくらないでください。

これらのどれもなしに悪魔払いを終えて、なんとか回避策を見つけたとしても、後でまた同じ問題に遭遇する可能性が高いです。

私が経験した FPGA 自身のバグの最も良い例は、ずいぶん前の Xilinx Virtex-4 のハードウェア FIFO に関するものです。つまり、FIFO の制御ロジックがシリコン上に直接実装されている(ロジックファブリックではない)デュアルクロック FIFO です。

その FIFO を通過するデータフローは、ときどき止まってしまいました。調査の結果、FIFO がしばらく正常に動作した後、empty(空)信号と full(満杯)信号が同時に active になっていることがわかりました。これは不正な状態です。FIFO がリセット中であれば別ですが、そうではありませんでした。そこで、自分が正しい信号を観測していることを完全に確認したうえで、FPGA の FIFO にバグがあるという結論でこの件を締めくくりました。そして、ロジックファブリックで実装される FIFO に切り替えました。

数か月後、この FIFO に関するエラッタを見つけました。その内容は、事前に問題を知っていなければ理解できなかったでしょう。しかし、説明を非常に注意深く読んだ結果、それが自分の観測を裏付けていると結論できました。

これは、FPGA のバグがどの程度明白であれば「自分のせいではない」と宣言してよいかを示す、一例にすぎません。

まとめ

FPGA が自然の法則に反しているように見えるとき、常識から外れた説明を受け入れたくなるものです。それでも、合理的な説明を探すことが重要です。そして、その説明は、スーパーパワーなしでも見つかることがよくあります。

しかし、原因の追及には設計の徹底的な見直しが必要かもしれませんが、それは必ずしも悪いことではありません。もどかしい作業ではあっても、その見直しは、結果的に設計の品質向上に大きく貢献する可能性があります。

このページは英語から機械翻訳されたものです。不明な点があれば、原文を参照してください。
Copyright © 2021-2026. All rights reserved. (dcc38493)