USRP のデータクロックから派生クロックを生成 AI で作りたい!!(2)

こんにちはドルフィンシステムの笹生です。


今回は「USRP のデータクロックから派生クロックを生成 AI で作りたい!!(2)」というタイトルで昨年10月の記事「USRP のデータクロックから派生クロックを作りたい!!(1)」の続きとなります。

2025年の最初からマニアックな話題で恐縮です。

前回の記事では、デフォルトでは作成できない派生クロックを CLIP の機能を使えば作成できるという内容でした。

今回は、その CLIP で取り込む外部の HDL(FPGA等を開発するためのハードウェア記述言語) を流行りの生成 AI で作成してみたというお話です。

※今回のバナーの図は Image FX という Google の画像生成 AI で作成してみました。プトンプトには英語化したタイトルを与えました。DALL-E3 で生成される画像とはまた違った趣ですね。(なんだかブロック図に説明調の文字が書いてありますが意味不明ですね。もっと凝ったプロンプトならましになるのかな?)

派生クロックを生成する VHDL を生成 AI で作成してみる

今回は Claude 3.5 Sonnet で作成してみました。

chatGPT でも同じプロンプトで作成してみたのですが、当時は 4o が最新でしたがちょっとたたき台として使用する Xilinx IP がうまく使えていない、より複雑な感じの使い方のようだったので、Claude の方で作成しました。

初期プロンプトは以下の様に与えました。

Xilinx の FPGA 用で、MMCX を利用して入力の 200MHzクロック信号を 160MHz のクロックにして出力する VHDL コードを作成してくれますか?

そもそも MMCM と書きたかったものを MMCX と間違えて入力していますが、Claude はきちんと意を汲んでくれました。


はい、Xilinx FPGA で 200MHz の入力クロックを 160MHz に変換する VHDL コードを作成します。この変換には、Xilinx の Mixed-Mode Clock Manager (MMCM) を使用します。

このVHDLコードは、Xilinx FPGAの Mixed-Mode Clock Manager (MMCM) を使用して、200MHz の入力クロックを 160MHz に変換します。以下に、コードの主要な部分について説明します:

  1. MMCME2_BASE コンポーネントを使用しています。これは Xilinx の 7 シリーズ FPGA で利用可能な MMCM の基本的な実装です。
  2. クロック変換のパラメータ:
    • 入力クロック: 200MHz (周期 5ns)
    • 出力クロック: 160MHz
    • CLKFBOUT_MULT_F = 24.0 (VCO周波数を設定)
    • CLKOUT0_DIVIDE_F = 30.0 (出力クロック周波数を設定)
  3. これらの設定により、(200MHz * 24) / 30 = 160MHz の出力クロックが生成されます。
  4. エンティティには clk_in (入力クロック)、reset (リセット信号)、clk_out (出力クロック) のポートがあります。
  5. MMCMのロック信号も生成されますが、この例では使用していません。必要に応じて、これを外部に出力することもできます。

このコードをXilinx の開発環境(Vivado など)で合成し、適切な制約ファイルを追加することで、FPGAに実装できます。入力クロックにはMMCXコネクタを使用し、適切なI/O規格を設定してください。

コードの動作や修正について、さらに詳しい説明が必要な場合はお知らせください。


この段階で生成されたコード(四角で囲われた </> の部分)ですでに文法的には問題もなく、かなり正しいコードを出力してくれたのですが、 パラメータの与え方で 24倍して 30で割っている(一旦 4.8GHz に上げてから160Hz に落とす)部分が MMCM IP の周波数範囲外になってしまうため、以下の様に修正してもらうプロンプトを与えました。

CLKFBOUT_MULT_F = 4にしてCLKOUT0_DIVIDE_F = 5 でも同じ結果になりますか?

こうすれば、一旦 800MHz に上げて 160MHz に落とすということになり、IP の周波数範囲に入ります。すると、Claude は修正した VHDL のコードを生成してくれました。

はい、その通りです。CLKFBOUT_MULT_F = 4 と CLKOUT0_DIVIDE_F = 5 の組み合わせでも、200MHz から 160MHz への変換という同じ結果が得られます。この設定の妥当性について詳しく説明しましょう。

この新しい設定の妥当性を確認しましょう:

  1. 周波数計算: 出力周波数 = 入力周波数 * (CLKFBOUT_MULT_F / CLKOUT0_DIVIDE_F) 160MHz = 200MHz * (4 / 5)
  2. VCO(電圧制御発振器)周波数: VCO周波数 = 入力周波数 * CLKFBOUT_MULT_F VCO周波数 = 200MHz * 4 = 800MHz

この設定は以前のものと同じ結果を生み出しますが、いくつかの違いがあります:

  1. VCO周波数が低くなっています(以前は4.8GHz、今回は800MHz)。
  2. 乗数と除数が小さくなったため、ジッタ性能が若干改善される可能性があります。
  3. より小さな値を使用することで、MMCM のリソース使用量が若干減少する可能性があります。

ただし、この設定にも注意点があります:

  1. VCO周波数が Xilinx の推奨範囲内(通常600MHz〜1440MHz)にあることを確認してください。800MHzはこの範囲内ですが、デバイスの仕様を必ず確認してください。
  2. クロックの品質(ジッタなど)は、具体的なFPGAデバイスやボード設計によって影響を受ける可能性があります。実際の使用時には、タイミング解析とシミュレーションを行うことをお勧めします。

最適な設定は具体的な要件(消費電力、タイミング制約など)によって異なる場合があります。必要に応じて、両方の設定をテストし、よりよい結果を選択することも一案です。

 

これを組み込んでコンパイルしましたが、エラーが出てしまいました。そのエラーコードをそのままプロンプトにコピペします。

ERROR: [Place 30-154] Unroutable Placement! A MMCM can only drive loads in the same clock region. The following MMCM clock loads are placed too far from the MMCM to be routable. 

 :<途中省略>

ERROR: [Place 30-99] Placer failed with error: 'IO Clock Placer failed'

Please review all ERROR, CRITICAL WARNING, and WARNING messages during placement to understand the cause for failure.

Ending Placer Task | Checksum: 1324fd00d


するとこのエラーに対して Claude が以下の様に対応方法のアドバイスをしてくれました。

このエラーメッセージは、MMCM(Mixed-Mode Clock Manager)とそのクロック負荷の配置に関する問題を示しています。主な問題点は、MMCMが駆動するクロック負荷が、MMCMと同じクロック領域に配置されていないことです。これを解決するためにいくつかの方法があります:

  1. CLOCK_DEDICATED_ROUTE制約の使用: CLOCK_DEDICATED_ROUTE=BACKBONE 制約を使用することで、クロック信号がより長い距離を伝搬できるようになります。
  2. バッファの追加: MMCMの出力にグローバルクロックバッファ(BUFG)を追加することで、クロック信号の分配を改善できる場合があります。
  3. フロアプランニング: MMCMとそのクロック負荷を同じクロック領域に配置するように、フロアプランニング制約を追加します。
  4. クロックネットワークの再設計: クロック分配ネットワークを再設計し、MMCMをクロック負荷により近い位置に配置することを検討します。
  5. LOC制約の確認: エラーメッセージに記載されているコンポーネント(例:OLOGIC_X0Y57など)に対するLOC制約を確認し、必要に応じて調整します。
  6. クロック領域の確認: 使用しているFPGAデバイスのクロック領域を確認し、MMCMと負荷が適切な領域に配置されるようにします。

これらの方法を試してみて、問題が解決しない場合は、デザイン全体のクロックアーキテクチャを見直す必要があるかもしれません。また、Xilinxのサポートフォーラムや公式ドキュメントも参照すると、より具体的な解決策が見つかる可能性があります。

 ここでは、コード的に対処できる 2. のバッファの追加をプロンプトで指示してみます。

BUFGを追加してくれますか

すると、BUFG を追加したコードを生成してくれました。

 もちろんです。MMCMの出力にBUFG(グローバルクロックバッファ)を追加することで、クロック信号の分配を改善し、配置の問題を解決できる可能性があります。VHDLコードを更新して、BUFGを追加しましょう。

このコードでの主な変更点は以下の通りです:

  1. clk_mmcmという新しい中間信号を導入しました。これはMMCMの出力を一時的に保持します。
  2. MMCMのCLKOUT0出力をclk_mmcm信号に接続しました。
  3. BUFGコンポーネントを追加し、その入力にclk_mmcmを接続し、出力をclk_outポートに接続しました。

この変更により、MMCMの出力がグローバルクロックバッファを通して分配されるようになります。これにより、クロック信号がFPGA全体により効率的に伝播され、タイミングの改善や配置の問題解決につながる可能性があります。

BUFGを追加することで、以下のメリットが期待できます:

  1. クロック信号の強化:BUFGはクロック信号を強化し、より多くのクロック負荷を駆動できるようにします。
  2. スキューの削減:グローバルクロックネットワークを使用することで、クロックスキューが削減されます。
  3. 配置の柔軟性向上:BUFGを使用することで、クロック負荷をFPGA上のより広い範囲に配置できるようになります。

この変更を適用した後、再度合成とインプリメンテーションを実行してください。それでも問題が解決しない場合は、フロアプランニングや他の制約の調整が必要かもしれません。その際は、さらなる分析と対策が必要になるでしょう。

この生成したコードは無事にコンパイルが通り、問題なく所望の動作をさせることができました。

まとめ

意外と VHDL のコード生成に生成 AI は使えるようになってきているなあというのが感想でした。単純なコンポーネントであれば比較的簡単に生成してくれそうな感じです。

とは言え、生成されたコードが正しいのか、コンパイルしてエラーが起きた場合のアドバイス指示としてどれが最適な指示なのかなどは、自分で記述ができる前提がないと難しいだろうなとは思います。



0 件のコメント :

コメントを投稿