電子回路わからん日記

にゃーんと言いながら電子回路いじってます

PT8211S DAC基板ができました

ご無沙汰してます。

やっと全部品が実装できました。

PT8211S自体は2022年に秋月電子通商で購入済でしたが、安定化電源が足りなかったり基板設計に時間がかかったり興味が薄れたりでなかなか進んでいませんでした。

audio-diy.hatenablog.com

テスト期間に部屋の掃除がしたくなるように(?)、GWに電子工作したくなったのでさっさと作ってしまいました。


DACボードの構成

特段変わったことはしていません。DAC出力後のフィルタ回路もPT8211データシート記載の定数で作っています。

データシートを見て疑問に思ったんですが、ポストフィルタ回路がサレン・キー型なのは何か理由があるんですかね・・・?

PT8211ポストフィルタの推奨定数

オペアンプは出力オフセット調整ができるということでSA5534A(5532の1回路・高精度・外部位相補償版です)を使用しました。

www.ti.com

PT8211のデータシートでは、PT8211の電源にRCローパスフィルタを使用していますが「電源ラインに抵抗」というのが個人的には気持ち悪さを感じるのでLT1761を直近で使用する構成にしました。

www.analog.com

ポストフィルタ回路のコンデンサは全てフィルムコンデンサを使用しましたが、データシート上の33pFはDigikeyだと取り扱いが少なく、WIMA一択になります。

www.mouser.jp

音質とか追求するようなICでもないと思うのでC0G特性のMLCCを使用したほうが無難でしょう。


測定環境構築

技術者の端くれたるもの、DAC(というか回路)を作ったからには測定したくなるものです。

実は2年近く前に強力なオーディオ測定機器を購入していました。

このCosmos ADCですが、

innocent-key.com

数万円で手に入る非常に高性能なADCとなっています。また測定に使用するソフトウェアですが、

www.roomeqwizard.com

フリーソフトで測定可能とのことで、ここまで来てしまうとオーディオメーカーは迂闊なものを作れないですね・・・

測定環境構築にはblue-7 (  )氏の以下の記事を参考に構築しました。

qiita.com


いざ、測定!

ということで測定しようと思ったのですが、なんかやたらとTHD+Nが悪い(0.7%ほど)です。

色々見ていくと・・・

状況をまとめると、

  1. 測定用PCと再生用PCは同じものを使用
  2. 電源(PCまたはモバイルバッテリー)にかかわらず、FPGA基板に給電した途端にノイズが現れる
  3. モバイルバッテリーは安定化電源を通じ必ずPT8211S用のレギュレータに対し給電している
  4. PCからFPGAに給電している場合、FPGA基板とDAC基板間のGNDワイヤーを抜くとノイズが消える
  5. モバイルバッテリーからFPGAに給電している場合、FPGA基板とDAC基板間のGNDワイヤーの有無に関わらずノイズが発生する。

これらからFPGA基板上のスイッチングレギュレータのスイッチングノイズがGNDループにより測定機器側に流れ込んでいると予想しました。

ノイズが出ているときのFFT波形は以下のような感じです。


環境を見直して・・・

とりあえずはFPGAへの給電をPCから行い、FPGADAC間のGND接続をなくせばループは絶たれるのでその方法で計測しました。

THD+Nが0.062%と、PT8211Sのデータシートと比較して良すぎる値が出ています。

384kHz fsで1kHz正弦波再生時の波形

PT8211SのTHD+N公称値

まぁデータシート上にどんな回路で測定されたか記載もありませんので、データシートの値がかなりマージンを持たせてあるか、AUDIYの測定ミスのどちらかだと思います。


ところで

その他、現状わかっていることとしては相互変調歪(?)がしっかり出ています。

以下、48kHz fsで1kHz正弦波を再生したときのFFT

48kHz fsで1kHz正弦波再生時のFFT

44.1kHz fsで1kHz正弦波を再生したときでスペクトルに大きな違いが見られます。

44.1kHz fsで1kHz正弦波を再生したときのFFT

同じ1kHz正弦波だと、44.1kHz系統(44.1/88.2/176.4/352.8kHz)と48kHz(48/96/192/384kHz)の間に同様の傾向が見られました。

ひょっとしてと思い、44.1kHz fsで918.75Hz(1000[Hz] * (44.1/48) = 918.75)正弦波を再生したところ、

44.1kHz fsで918.75Hz正弦波を再生したときのFFT

ビンゴです。

352.8kHz fsでも同様の結果が得られたので、再生する音源に含まれる周波数と送信するデータの周波数の差分が悪さしているのは間違いなさそうです。


ということで、出来上がったPT8211S 自作USB-DACFFT波形を取ってみました。

AUDIY自身まだまだこの測定環境の使い方がわかっていない点も多い(0dBFSの合わせ方とか)ので、理解しながら他の特性(S/N日など)も見ていきたいと思います。

最近ずっとFPGAでしたがやっと電子工作っぽいことができるようになってきました(なおインフレで部品代がツラいです・・・)。

 

Verilator、(Linterとして)はじめました。

どもです。

これから暖かくなるので、

Verilator(冷やし中華)、はじめました。w


Verilatorとは

Veripoolが開発するオープンソースVerilog/SystemVerilogシミュレータです。

www.veripool.org

テストベンチやモジュールをマルチスレッド(!)のC++コードに変換(公式ではこの変換を"Verilate"と呼んでいます)し、C++コンパイラで実行可能形式にコンパイル後、実行することで高速なシミュレーションを実現しているのがウリのようです。

名だたる半導体メーカー(WD、Intel、NXPなど)でも使用されており、Chips AllianceやLinux Foundationから支援を受けているなど、業界ではかなり有名な様子。

公式では「Synopsys(VCS)/Siemens(Questa/ModelSim)/Cadence(Xcelium/Incisive/NC-Sim)と合わせた4大シミュレータの一つ」と豪語しています(本当か?)

veripool.org

AUDIY自身、Verilatorの勉強会を数年前に受けたことがあり、個人的には興味を持っていましたが当時はC++での記述が大量に出てきて正直「これならシミュレーションはIcarus VerilogとかQuartus等に付属しているやつで良いかな」という印象でした。

connpass.com


導入方法

主に3通りの導入方法があります。

veripool.org

それぞれの導入方法でのメリット・デメリットは以下の通りとなります。

パッケージマネージャを使用する

メリット
  • 確実に安定版が導入できる
  • 依存関係も合わせてインストールしてくれる
デメリット

gitからソースコードを入手しビルドする

メリット
  • 常に最新版を導入できる
  • パッケージマネージャで自動的にバージョンアップされないので特定のバージョンを長く使用可能
デメリット
  • 依存関係を自分で調べて導入しておく必要がある
  • OSや依存関係とのバージョンの整合性が取れないときにインストールに失敗する場合がある
  • 最新版導入のたびにビルドの必要がある

Dockerを使用する

メリット
  • ビルドせずに最新版を導入可能
  • 常に最新版を導入できる
  • コンテナを利用しているので依存関係を気にしなくて良い
デメリット
  • Dockerの知識が必要
  • Verilatorでは自前の環境より動作に若干時間がかかる
  • VerilatorではVSCodeとの連携が困難

今回はVSCodeプラグインと連携させてLinter機能を使いたかったのと、AUDIYが使っているUbuntu 22.04 LTSではパッケージマネージャで配布されてるVerilatorのバージョンが4と古いので、gitからソースコードを入手しビルドしたいと思います。


ビルド方法

今回はWindowsマシン上にWSL2 + Ubuntu 22.04を構築して導入したいと思います。

WSL2の導入はこの記事が詳しいと思います。

www.aise.ics.saitama-u.ac.jp

Ubuntuが導入できたらあとは以下のページの内容の通りに依存関係を導入してインストールすれば問題ないと思います。

Ubuntu 22.04の場合では「zlibcが無い」とエラーが出ますが、その場合は無視して良いです。

veripool.org

ちなみにですが、

それ以前はC++でテストベンチ書く必要があったようですね・・・・
ちなみにC++テストベンチのサンプルコードはカオスです。

dora.bk.tsukuba.ac.jp


動かしてみる

テストベンチから実行形式を吐き出してみます。
とりあえずでてきた警告は無視させています。

github.com

 

  • verilator --cc --binary --timing --trace --trace-params --trace-structs --trace-underscore -Wno-TIMESCALEMOD -Wno-WIDTHTRUNC +1364-2005ext+v SDPRAM_SINGLECLK_tb.v

 

成功するとobj_dirというディレクトリ内に実行ファイルができますので、メモリ初期化ファイル(ram_init_file.mem)を同一ディレクトリに置いて

  • ./VSDPRAM_SINGLECLK_tb

 

vcdファイルが作成されるので、gtkwaveで読み込めば

 

vcd出力の際にオプションが必要になったり、一部のVerilog記述のシミュレーションが非対応だったり、

msyksphinz.hatenablog.com

Warningが出力される時点で実行形式は生成されない(厳しいな・・・・)ので、単純なシミュレーションだけであればIcarus Verilogの方が実行オプションも少なく使いやすい印象です。

github.com

 

WarningやErrorは結構細かい内容が網羅されている(悪く言えば制限が強い)ので、AUDIYのような「コーディングルールがフラフラしがち」な人には良い矯正ツールだと思います。


そこで考えた

「これ、Linterとして使えないか・・・?」

そこでAUDIYが使っているVSCodeVerilogプラグインを調べてみると・・・・

marketplace.visualstudio.com

・・・・・ありました。

Verilatorと連携してVSCode内のLinterとして使えます!

もう少し設定を追っていきますと・・・

 

Verilatorの実行オプションを追加できたり

WSL上に構築したVerilatorを使用することもできるようです。

それではやっていきましょう。

Verilog > Linting: Linter」を"verilator"に設定します。

Verilog > Linting > Verilator: Arguments」に必要なオプションを追加します。
AUDIYの場合は「警告を全て出力」「遅延評価する」「Verilog記法はVerilog-2005で指定」にしました。

Verilog > Linting > Verilator: Run At File Location」と「Verilog > Linting > Verilator: Use WSL」にともにチェックを付けます。

ではLinter実行結果を見ていきましょう。


Icarus VerilogとLint結果を比較

Icarus Verilog

なるほどなるほど・・・

"syntax error"を教えてくれるのは良いんですが何がどうダメなのか・・・

この行は問題ないのにその前の行のエラーに引っ張られてエラーになってしまっています・・・

Verilator

「"="がおかしくない?」とエラー箇所を推測しています

ここも同様ですね。「"end"周辺がおかしい」とわかります。

Icarus VerilogのLint機能にはありませんでしたが、VerilatorだとWarningも出してくれます。

「順序回路の中でブロッキング代入使ってるけど大丈夫?」というWarningです。

「ファイル末尾は行を入れておくのが推奨ですよ」とまで。かなり丁寧ですね。


ということで、VerilatorをLinterとして導入しました。

AUDIYのXには

github.com

とオススメもありましたが、こちらガチガチのSystemVerilogルールでLint(wire, reg宣言すらもWarningにするほどには)してて、Verilog主体のAUDIYにはまだまだ早い感じでした(設定ファイルを編集してLintルールを細かく設定できるのでいずれは使いこなしたい)。

WindowsのみならずLinuxマシンにも導入しているので、Linterのみならずシミュレータとしても使っていければと思います。

CMOD S7でMicroBlazeやってみる(後編)

どもです。

前回はDigilent公式のベアメタルプログラミングのチュートリアルをもとに、CMOD S7にMicroBlazeとそれを動かすための周辺ブロック(メモリとかクロックとかUARTとか)を配置するところまでやりました。

digilent.com

audio-diy.hatenablog.com

今回はその続きとしてLEDを光らせるためのボタンやLEDとFPGAの接続(GPIO)やVitisを使用したMicroBlaze上で動かすソフトウェアの実装と書き込み、実際の動作確認までやっていきたいと思います。

それでは早速いきましょー


前回の続き

GPIOをブロックに追加する

今回はボード上のコンポーネント(LEDとか)からGPIOブロックを接続していきます。

Diagramの左にある小さなウィンドウの"Board"タブより"GPIO"の一覧から"4LEDs"を右クリックして、「Connect Board Component」を選択します。

以下のようなウィンドウが開くので、"AXI GPIO"一覧の"GPIO"を選択し"OK"をクリックします。

追加されたGPIOブロック"axi_gpio_0"をクリックすると、左下にBlock Propertiesが表示されますので、

Nameに"AXI_GPIO_LED"とすると名前が変化します。今後オリジナルのプロジェクトを作る際に、わかりやすい名前のブロックにしておくために覚えておくと良いと思います。

次はBoard Componentからではなく、Block DiagramからGPIO IPを追加してBTN1(タクトスイッチ)と接続してみます。Block Diagram上列の"+"ボタンをクリックします。

検索欄が出てくるので"gpio"と入力し、表示される"AXI GPIO"をダブルクリックします。

AXI_GPIO_LEDと同様に、このブロックの名前を変更します。BTN1と接続するので、"AXI_GPIO_BTN1"としました。

Digilent用XDCファイルをダウンロードする

ここで一回Vivadoから離れて、環境設定に移りたいと思います。

なんとDigilentは販売しているFPGAボードに合わせたXDCファイルも準備してくれています。

www.acri.c.titech.ac.jpこれを入れておくとだいぶ楽になるので、入れておきたいと思います。

まず、以下のリンク先からXDCファイル一式をダウンロードします(自動ダウンロードされるので注意してください)。

https://digilent.com/reference/lib/exe/fetch.php?tok=a49a20&media=https%3A%2F%2Fgithub.com%2FDigilent%2Fdigilent-xdc%2Farchive%2Fmaster.zip

ダウンロードされたZIPファイルを展開し、紛失しないよう任意の場所に保存しておきます。

Vivadoに戻り、左側のメニューの"PROJECT MANAGER"一覧から"Add Sources"を選択します。

以下のようなウィンドウが表示されるので、"Add or create constraints"を選択し、"Next"をクリックします。

"Add Files"を選択します。

XDCファイル一式を保存したフォルダに移動し、使用するボードに対応したXDCファイル(今回の場合は"Cmod-S7-25-Master.xdc")を選択し"OK"をクリックします。

ファイルが選択されたら"Copy constraints files into project"にチェックを入れ"Finish"を選択します(チェックを入れておくことで今回使っているプロジェクト用にXDCファイルがコピーされ、ダウンロードしたXDCファイルが上書きされるのを防ぎます。なんという親切設計!)。

AXI_GPIO_BTN1とBTN1を接続する

Block Diagramの左側のショウウィンドウから"Sources"タブを選択し、"Constraints"から、先程追加したXDCファイルをダブルクリックすると、Block Diagramと同じウィンドウにXDCファイルが表示されます。

btn[1]だけコメントアウト("#")を外します。

Block Diagramに戻り、AXI_GPIO_BTN1の"GPIO"の文字列を右クリックし、"Make External"を選択します。

するとブロックが何か出力っぽいものと配線されます。

つながった先は"GPIO_0"になっているかと思いますので、IPのブロック名変更と同様の手順で、XDCに記載されているボタンのネット名"btn"にしておきます。

ここから少し作業が細かくなってきます。AXI_GPIO_BTN1ブロックを拡大し、"GPIO"の横にある"+"をクリックすると・・・

こんな感じで"gpio_io_i[31:0]"、"gpio_io_o[31:0]"、"gpio_io_t[31:0]"が見えるようになります。

このままだと32bitのGPIOとして認識されますので、BTN1の数となるように調整する必要があります。

AXI_GPIO_BTN1をダブルクリックして、IP設定画面を開きます。

"IP Configuration"のタブを開き、"All Inputs"にチェックを入れて、"GPIO_Width"を1に設定し、"OK"をクリックします。

GPIOブロックとMicroBlazeや周辺ブロックと自動で接続してしまいます。Diagram内の"Run Connection Automation"をクリックします。

"All Automation"にチェックを入れ、"OK"をクリックします。

デザインを検証する

ここまで設計したデザインが問題ないか確認します。Block Diagramの"Validate Design"をクリックします。

問題がなければ以下のようなメッセージが表示されます。

HDL Wrapperを生成する

Validate Designで問題なければHDL Wrapperを生成します。

Diagram左のウィンドウから"Sources"タブを選択し、"Microblaze_blink"を右クリックして"Create HDL Wrapper..."を選択します。

以下のようなウィンドウが出てきます。"Let Vivado manage wrapper and auto-update"を選択して"OK"をクリックします。

コンパイルする

コンパイルします。左側のメニューから"Generate Bitstream"を選択します。

今回の例では論理合成や配置配線をしないまま選択するので以下のようなメッセージが表示されますが、"Yes"をクリックします。

論理合成・配置配線されていない場合はそこから始めてくれます。

コンパイル(論理合成・配置配線)の設定ウィンドウが開きます。
"Launch directory"はそのまま、Optionsは"Launch runs on local host"(開発環境のCPUパワーのみを使う)にします。
"Number of jobs"はコンパイルに使用するCPUのスレッド数です。多いほど早く終了しますが、他のソフトウェアがフリーズする可能性もあるため、マルチタスクコンパイルしながら資料を作るなど)する場合は注意が必要です。今回は実際に扱うLinuxマシンで最大の"12"に設定して時間を測ってみます。

設定が完了したら"OK"をクリックします。

・・・・と思ったらVivadoが落ちました。デフォルトの"6"で再度試します。

 

エラーが出ました。3 errorsの部分をクリックしてメッセージを表示してみます。

なんか長いのが出てきてますが、「btn_tri_i[0]が配線されていない」といったメッセージでした。XDCファイルを開き直して、btn[1]をbtn_tri_io[0]にして再度コンパイルをやり直してみます。

コンパイル完了しました。正直XDC周りがよくわかっていないのがお恥ずかしい限りです・・・(やってみた記事なので寛容にみていただけると幸いです。)
コンパイルにかかった時間は2分弱です。

何をするかを選び"OK"をクリックするか、そのまま何もしない場合は"Cancel"をクリックします。

Hardware Platformを出力する

Vivadoで作成したハードウェア情報をVitisで使用できるようにHardware Platform(XSAファイル)を出力します。

これがあるとVitis側からソフトウェアとハードウェアをまとめて書き込むことが可能です。

Vivadoのメニューから"File"→"Export"→"Export Hardware"を選択します。

以下のウィンドウが開きますので"Next"をクリックします。

"Include Bitstream"を選択し、"Next"をクリックします。

出力するXSAファイル名と出力先を選択し、"Next"をクリックします。

最終確認の画面が出ますので、保存場所や出力形式に間違いがなければ"Finish"をクリックします。

これにてVivado側での作業は終了です。熱いお茶と和菓子で一服しましょう。笑


Vitisでソフトウェアを設計する

最近知ったんですが「ヴィティス」じゃなくて「ヴァイティス」だそうです。

Vitisを立ち上げる

Vitisを立ち上げてソフトウェアを開発していきます。

VitisはVisual Studio Codeベースの"Vitis Unified IDE"とEclipseベースの"Vitis Classic"があります。Vitis ClassicはDeprecatedとなっているため、近い将来に使用不可能と鳴る可能性があります。

今回、Vitis Unified IDEでの開発を試みましたが、この記事を書いている時点でビルドに失敗する状況なので、公式チュートリアルどおりにVitis Classicで開発していきたいと思います。

以下の"Vitis Classic 2023.2"が今回使用するVitis(以下Vitis ClassicをVitisと呼びます)です。

Workspaceを選択する

Vitisを立ち上げると、ソフトウェアの開発に必要なファイル一式を保存する場所(これを"Workspace"と呼びます)を選択する画面が立ち上がります。

今回はVivadoプロジェクト保存場所"Digilent_Microblaze_Tutorial"の直下に"Vitis_Workspace_Classic"というフォルダを作りWorkspaceに指定しました。

VitisではWorkspace指定後にVitis Unified IDEへの移行を促すメッセージがでますが、今回は無視して"Continue With classic Vitis"を選択します。

Application Projectを作成する

Vitisの初期画面が表示されますので、"Create Application Project"を選択します。

プロジェクト作成フローの説明画面が出てきます。"Next"をクリックします。

Platform選択画面に移ります。今回はVivadoで出力したXSAファイルを使用しますので、"Create a new platform from hardware (XSA)"のタブを選択し"Browse"ボタンをクリックして、

XSAファイルを指定し、"Next"をクリックします。

Application Projectの名前を決めます。基本的に半角スペースや特殊文字がなければどんな名前でも良いと思います。今回は"Microblaze_blink_app"としました。
名前を入力したら"Next"をクリックします。

Domainを決めます。今回はMicroBlazeをベアメタルで動かすので、Operating Systemの欄が"standalone"、Processorの欄が"microblaze_0"になっていることを確認し、"Next"をクリックします。

設計するソフトウェアをテンプレートから設計できます。Digilent公式では"Empty Aplication (C)"からやっていますが、

とのことなので、習慣づけの意味も込めてHello Worldを選択し"Finish"をクリックします。

すると必要なファイルが自動で生成され、以下のような画面表示になります(うーん、がっつりEclipse!)。

プログラムを作成する

Hello Worldからプロジェクトを生成すると、自動で"helloworld.c"というエントリポイントが作られるので開いてみます。

コレとDigilent公式チュートリアルのプログラムを合体させて、以下のようなソースコードにしました。

プログラムを一部修正する

公式チュートリアルからボードが違っていたり、変数・定数名が変わっていたりするので修正します。

"xparameters.h"を確認し、ボタンとLEDに対応するGPIOのデバイスID定数名をエントリポイント側で変更します。

AUDIYの場合は、"XPAR_AXI_GPIO_BUTTONS_DEVICE_ID"を"XPAR_AXI_GPIO_BTN1_DEVICE_ID"に変更する必要がありました。

また、"helloworld.c"内の"BTN_MASK"の値を0b1111から0b0001に変更します。
これは公式チュートリアルで使用するボタン数の想定が4なのに対し、今回はBTN1の1つしか使用しないためです。

ここまでできたらhelloworld.cを保存します。

プログラムをビルドする

Systemの項目(今回の例では"Microblaze_blink_app_system")を選択した状態で、ハンマー(トンカチ?)の絵のボタンをクリックするとビルドが開始されます。

ビルドに成功すると以下のような表示がウィンドウ下部のコンソールに表示されます。


動作確認

さてさて、動作確認します。

動作確認の前に以下の環境を整えておきます。

  1. AMD FPGA用ケーブルドライバのインストール
  2. Tera term(Windows)、GTKterm(Linux)のインストール

GTKtermについては下記記事がわかりやすいと思います。

zenn.dev

ターミナル立ち上げ

GTKtermを立ち上げてUSB-UARTシリアル通信のためにポートを開けておきます。
設定は以下のようになります。ボーレートにご注意ください。

プログラムの実行

Vitisのウィンドウに戻り、Application Projectを選択して右クリック→"Run As"→"Launch Hardware (Single Application Debug)"をクリックします。

うまく行くと以下の動画の用にGTKterm上に"Entered function main"と表示され、、BTN1を押すと4つのLEDが点灯します。

ここまで完了した方、お疲れ様でした!

少し改造して、ボタンを押したときと話した時に表示するようにしたり、これからドシドシ遊んでください。


以上、Linuxマシン+CMOD S7で行うMicroBlazeチュートリアルでした。

個人的には「慣れてしまえばIntel FPGAよりもソフトウェアの開発の難易度は低いかもしれない」と感じましたが、今回の「やってみた」記事だとなかなかそのあたりは伝わりにくいかもしれません。

ぜひぜひDigilentFPGAボードを入手された方は本家チュートリアルと格闘しながら個々のボードに合わせて修正してみてください。

さてさてこれでLinuxマシンでとりあえずAMD FPGAと通信できることがわかったので、もう少しツールに慣れたらKRIA KR260と再び格闘することにしたいと思います。(自分が情報系の学部を卒業してから暫く経ってて最近のトレンドについていけていないですし、せっかくLinuxマシンを入手したのでそのあたりリハビリしたいですね)

それでは。

CMOD S7でMicroBlazeやってみる(前編)

どもです。

どうやらEfinixのFPGA書き込み用ドライバによって標準ドライバ環境を破壊されたらしく、

もう二度とメインマシンにEfinix FPGAの開発環境入れませんわ・・・・

ドライバ環境を一からやり直すとなるとWindowsクリーンインストールしかなさそうなのですが、それはそれで時間がかかって面倒くさいのと、C言語でのソフトウェア開発でLinuxマシンがないと不便なこともあり・・・・・・

・・・・・・導入しました。

今は購入したThinkPadUbuntu入れてVitisやらDockerやらC/C++コンパイラやら入れて使ってます。

やっと開発環境も整いつつあるんで、今回は前回の続きとして、

audio-diy.hatenablog.com

CMOD S7にMicroBlazeを実装して動かすところから初めて、VivadoとVitisに一度触れてみたいと思います。


DigilentMicroBlazeチュートリアルを試す

DigilentFPGAボードのIntroductionを読んでいると、ページ下部に複数のチュートリアルが提供されています。

digilent.com

 

今回はこれに沿ってMicroBlazeをCMOD S7上のSpartan-7 FPGAに構築し、LチカおよびPCとのUSB-UART通信を実装してみたいと思います。


と、その前に・・・

DigilentFPGAボードですが、Digilentが公式でボードファイルを提供しているため、これを自身のVivado環境に導入します。
(多分なくてもできますが、あったほうがピン周りの配線の自動設定とかしてくれるので大変便利です。)

Digilentの"Installing Vivado, Vitis, and Digilent Board Files"にアクセスします。
(この時点でVivadoやVitisをインストールしていない方は合わせてやっちゃいましょう。)

digilent.com"Install Digilent's Board Files"の項までジャンプします。

digilent.com

そこから最新版のボードファイル一式をダウンロードするリンク("Master Branch ZIP Archive"と記載があります)をクリックするとDigilentのボードファイル一式がダウンロードされます。

ダウンロードされたZIPファイルを展開し、new/board_filesの中身をVivadoをインストールしたフォルダの/Xilinx/Vivado/<version>/data/boards/board_files内にコピー&ペーストします(board_filesフォルダがない場合は新規に作成し、その中にコピー&ペーストします)。

ここまでできたらチュートリアルを始めていきたいと思います。

本家のチュートリアルDigilentのあらゆるボードでできるようにところどころ表現がボカされていますので、ここではCMOD S7 & Ubuntuの開発環境に合わせ改変していきたいと思います。


やっていこう

以下リンク先に従ってチュートリアルをやっていきます。

digilent.com

Vivadoの立ち上げ

Vivadoを立ち上げます。

いろんなサイトを確認するとsettings64.shを使って環境変数を通してコマンドを叩いて開いていますが、Version 2023.2だとアプリケーション一覧のアイコンで開くことができました。

プロジェクトの作成

プロジェクトを作成していきます。

Quick Startから"Create Project"を選択します。

"Next"をクリックします。

プロジェクト名とプロジェクトの保存場所を決めます。
今回のプロジェクト名は"Digilent_Microblaze_Tutorial"としました。

プロジェクト形式を決めます。
"RTL Project"に設定し、"Do not specify sources at this time"のチェックボックスにチェックをつけて"Next"をクリックします。

使用するFPGAを選択します。デバイスから選択もできますが、今回はBoardから選択します。

Searchの欄に"cmod"と入力すると"Cmod S7-25"が出てくるので選択します。Digilentのボードファイルを導入していないと表示されないので注意してください。

ボードファイルを導入済みなのに出てこない場合は左下の"Refresh"をクリックしてみてください。それでも出てこない場合はボードファイルを格納した場所を再確認する必要があります。

 

以下はRefreshボタンをクリックした際の画面です。少し待ちます。

使用するボード(今回はCmod S7-25)を選択して"Next"をクリックします。

プロジェクトの概要が表示されますので、問題なければ"Finish"をクリックします。間違いがあれば"Back"をクリックして設定し直します。

ブロック図からMicroBlazeと周辺回路を構築する

現在開いているVivadoですが、RTLやIPの設定や配線、シミュレーション、ビットストリーム書き込みを行うための「AMDFPGAやSoCのハードウェアを担当するツール」となります。

ここからはCMOD S7上のSpartan-7にMicroBlazeを構築していきます。

AMD FPGAやSoCに初めて触れるかたは"MicroBlaze"や"Zynq"など混乱するかもしれませんが、

  • MicroBlazeAMD FPGAまたはSoCのユーザロジック(PL)上に構築されるCPU IP。ユーザロジックを使用するため自前のRTLを構築できる領域が減少し、動作速度も期待できないが低コスト。
  • Zynq:AMD SoC内にFPGA(PL)とは別に存在しているARMアーキテクチャのハードウェアCPU(PS)。ユーザロジックを使用せず、専用のマイコンが配置されているため動作速度はMicroBlazeより期待できるが、専用のマイコンがある分高コスト。

となります。

まぁAMDの場合はSoCそのものがZynqと命名されている(Versal除く)ため間違いは起きにくいと思いますが、今回使用するCMOD S7に配置されているSpartan-7は純粋なFPGAなので、今回はMicroBlazeを構築します(実はIntelがこのあたりちゃんと調査しないと分かりにくいんですよ・・・)

余談はこのあたりにしておきまして・・・

 

Vivado左側のメニューより"IP INTEGRATOR"一覧から"Create Block Design"を選択します。

以下のようなウィンドウが出てくるのでDesign nameを決めます。今回は"MicroBlaze_blink"としました。
DirectoryやSpecify source setの項目は何も触らず、"OK"をクリックします。
Design nameには" "(スペース)を使用しないようにしてください!代わりに"_"(アンダーバー)、"-"(ダッシュ)、キャメルケース(各単語の冒頭を大文字にする。今回のDesign nameだと"MicroblazeBlink")の使用が推奨されています。

ブロック図にMicroBlazeを配置する

いよいよMicroBlazeを構築していきます。

まずはMicroBlazeを動作させるためのクロックを設定します。

Diagramの隣にある小さなウィンドウから"Board"を選択し、"Clocks"一覧の"System Clock"を右クリックして"Connect Board Component"を選択します。

以下のウィンドウが出てくるので"clock_CLK_IN1"にのみチェックがついていることを確認して"OK"をクリックします。

外部リセットを自動で配置します。Diagram上に緑色のバーで表示されている"Run Connection Autometion"をクリックします。

以下のようなウィンドウが出てきます。左側のresetにチェックがついていることを確認します。Digilentのほとんどのボードで自動でリセットに繋がれるポートが選択されるので"OK"をクリックします(CMOD S7では基板上のBTN0をリセットとして配置します)。

ここで、Diagram上の"Clocking Wizard"をダブルクリックしてみます。

IPの設定画面が出てきます。詳細は割愛しますがリセットの極性やIP動作モード、出力数、出力クロックの周波数など細かく設定できます。

Output Clocksのタブをクリックするとクロック周波数や出力数がわかります。現在の設定では100MHzをclk_out1から出力します。

今回は何も設定を変更しないので、"Cancel"をクリックしてウィンドウを閉じます。

次にMicroBlazeを配置します。Diagramから上列の"+"ボタンをクリックします。
検索欄が出てくるので、"microblaze"と入力し、"MicroBlaze"をダブルクリックすると・・・

MicroBlazeが配置されます。
必要な周辺IPを配置する必要がありますがここはVivadoにまかせてしまいます。緑色のバーに表示されている"Run Block Alutomation"をクリックします。

以下のようなウィンドウが出てきます。MicroBlazeの設定に合わせ周辺ブロックも自動設定してくれます。

今回のチュートリアルをCMOD S7で行う場合は以下のように設定します。l

  • Preset: None
  • Local Memory: 32KB
  • Local Memory ECC: None
  • Cache Configuration: None
  • Debug Module: Debug Only
  • Peripheral AXI Port: Enabled
  • Interrupt Controller: チェックをつける
  • Clock Connection: /clk_wiz_0/clk_out1 (100MHz)

各項目の設計基準は以下のようになります(本家チュートリアルより抜粋)。

OKをクリックすると周辺ブロックの配置および配線が自動で行われます(すげぇなVivado!)

次にPCとのUSB-UART通信部を配置します。Diagram横の小さなウィンドウから"Board"タブを選択し、"UART"から"USB UART"を右クリックして"Connect Board Component"をクリックします。

以下のウィンドウが出てきます。"AXI Uartlite"下部にある"UART"を選択し、"OK"をクリックします。

Diagram上にUART通信部が配置されるので、緑色のバーに表示される"Run Connection Automation"をクリックします。

以下のウィンドウが出てきます。画面左側の"S_AXI"にチェックが入っていることを確認し、あとは設定を変更せず"OK"をクリックします。

こんな感じのブロック図になっていると思います(ブロックの位置や配線は環境により異なるかもしれません。)


ちょうど公式チュートリアルが半分進んだ感じなので、今回はここまでとします。

Vivadoのブロックの自動配置・配線機能は大変ありがたい機能に感じました。
ただ、各ブロックの接続が基本AXIなのと、触れないであろうブロックまで表示されるので全体の視認性は少々悪く感じます(それ故に自動配置の機能があるんだと思いますが)。

次回はボタンやLED等に接続されるGPIOの配置、コンパイルの制約、コンパイル、ビットストリームの生成、VitisでのLチカソフトウェア実装とソフトウェアの書き込みをやっていきます。

 

KRIA KR260 Robotics Starter Kitを購入しましたが・・・・

皆様明けましておめでとうございます。

昨年はどのような1年でしたか?
私は転職騒ぎから始まりましたが結局そのままの職場に残り現状はまぁまぁなんとかうまくやれております。

2024年もどうぞよろしくお願いいたします。


KRIA KR260をついに購入

ついに買ってしまいました。

購入した理由としては

  • FPGA & CPU & その他アクセラレータを組み合わせたシステム構築を勉強したい
  • GPIOが豊富
  • 同クラス単体FPGA評価ボードを買うより安価
  • いい加減AMD(旧Xilinx)のデバイス設計にも触れたい(Intel→Efinix→Gowinと来てAMDやってない)

というのがあります。


そもそもKRIAとは

AMDが公式に販売しているZynq Ultrascale+ MPSoCを搭載したSoM(System on Module)です。

japan.xilinx.com

Zynq Ultrascale+ MPSoCとほぼ確実に組み合わせて使うであろうDDRメモリや電源、TPM等の周辺部品をモジュール化して販売することで、開発者は基板設計の工数を削減できるという特徴を持ちます。(DDRなんかは設計も大変なので・・・)

今回購入したKR260にはK26ベースのSoMが搭載されており、使用されているデバイスはLUT数やビデオコーデックが搭載されていることからZU5EVと言われています。

Zynq Ultrascale+ MPSoC Selection Guide(XMP104)より抜粋

ZU5EVのデバイス概要ですが

  • CPU:Quad-Core ARM Cortex-A53
  • RPU:Dual-Core ARM Cortex-R5F
  • GPU:ARM Mali-400
  • PL(FPGA):256K Logic Cells, 1248 DSP Slices, 3.5Mb RAM, 187Mb UltraRAM

・・・・いやフルで使いこなせる気がしません。


さっそく動かしてみようとしますが・・・

こいつ(KR260)、これまで触ってきたFPGAとだいぶ気色が違います。

まず、チュートリアルが「Lチカ」なんて生易しいものではなく「KR260でOS(LinuxやROS2)を動かす前提」のものがほとんどです。

xilinx.github.io

しかもチュートリアルの多くはプロジェクト立ち上げからやる感じではなく、ビルド済のアプリケーションをKRIA SoM本体に組み込んで動かす感じです(コレはチュートリアルというより動作確認では・・・・)

AMD FPGAが初めてな私にとっては最初に購入するものを間違えてしまった感がすごいです・・・


とりあえず資料を読み漁る

かといって何もしなかったら何もできないままKR260がホコリを被ってしまいますから、すでにKR260を使用している先輩のアウトプットを探してみます。

すると、面白そうなものがありました。

zenn.dev

KR260ではなくKV260(ビジョンAI向け開発キット)ではありますが、個人的にはやっぱりこの手順から始めていきたいところです。

あと、AVNETのブログがこのあたり積極的にまとめはじめているようで、

www.avnet.com

Petalinuxを使ったり、Pynqを使ったり、デジタル信号処理(←!!)したりとなかなか充実度が高そうな内容です。

ただPetalinuxを使っているので、やはりPetalinux開発環境は整えないといけないですね(重い腰を上げますかー)


以上、KR260の購入報告&わけわからん報告でした。

公式資料ばかり見ててもちゃんと習得できるか怪しいので、DigilentのZynqボードのドキュメントとかも参考資料としていきたいところです。

なんかKRIA、「ハードウェア設計者のためのSoC」というよりも「ソフトウェア設計者がFPGA使ってハードウェアアクセラレーションをすぐに実装できるように作られたもの」という感じがしてきました・・・

2024年新年のご挨拶

どもです。

まず初めに、令和6年能登半島地震に被災された皆様に心よりお見舞い申し上げます。
だいぶ離れた地に住んでいますが、義援金等できることを少しずつ協力したく思います。


2024年・・・

皆様、新年あけましておめでとうございます。

元日からとんでもない事件や事故が続いた印象がありますが、皆様が無事に新年を迎えることができたのであれば幸いです。

ちなみにAUDIYは2023年の12月30~31日に原因不明の体調不良(腹痛、下痢、軽い吐き気、手先足先のしびれ)に遭い災難でした。

さて、今年はAUDIYが現在の職場に新卒入社して5年目に突入します。
2025年の4月に「入社5年の所感」を書けるようしっかりと一つ一つのできごとをまとめておければと思います。

audio-diy.hatenablog.com

今週のお題「2024年にやりたいこと」

ここでは2024年の目標を列挙して有言実行するための場として新年の挨拶にかえさせていただきたいと思います。


応用情報技術者の取得

AUDIYは一つ取得したい資格があります。
それは「エンベデッドシステムスペシャリスト」です。

www.ipa.go.jp

大学・大学院で情報工学を学んだ経験を回路設計(ハードウェア設計)に活かすことを考えたときに、その専門知識を証明する資格として最も近い資格の一つだとAUDIYは考えています。(というか回路設計が密接に関わる資格が少なすぎでは?)

その足がかりとして応用情報技術者を2024年10月取得めざして活動していきたいと思っています。

www.ipa.go.jp


デジタルフィルタIPの汎用性向上

2023年はPCM用の2倍オーバーサンプリングデジタルフィルタIPを公開しました。

github.com

現状は2倍オーバーサンプリングのみ行えるIPですので、「1/2デシメーション」および「フィルタリングのみ」が行えるよう修正して汎用性を高めたいところです。


SystemVerilogの習得

現在AUDIYはVerilog + PSLでRTL開発を行っていますが、これをSystemVerilog + SVAに昇華させたいです。

検証関係の機能がSystemVerilogのほうが充実しているのが最大の理由です。

www.accellera.org


アサーションベース検証本(?)の執筆

Intel FPGAの開発環境(Quartus Prime Lite)に標準付属のRTLシミュレータがModelSimからQuestaに変更になり、アサーションベース検証機能(SVA、PSL)が標準付属となりました。

これによって今までは環境の導入が高額であったアサーションベース検証の敷居がグッと低くなったと思います。

www.paltek.co.jp

AUDIYもこれに伴いアサーションを導入しましたので、そろそろ学んだことをアウトプットする機会を設けたいところです。


ソフトウェアプログラミングも積極的に

2023年はFPGAやRTL一辺倒でしたが、2024年はマイコンやPCアプリケーションの開発も合間を縫って積極的に行っていきたいところです。

github.com

github.com


転職活動

今すぐ転職するとかではないですが、何かあったときのために日頃から履歴書・職務経歴書は作成・更新しておきたいところです。

良さげなサービスを見つけたので試してみようかしら・・・

rirekisho.yagish.jp


と、2024年もやりたいことが満載でございます。w

もちろんこの中でできること、できないことは出てくるでしょうがそれはまた2024年の年末にでも振り返りたいと思います。

一番難易度が高いのは応用情報技術者試験の合格だと思いますので、ここを重点的に行なっていければと思います。

 

2024年もよろしくお願いいたします。

 

 

PCM用自作オーバーサンプリングデジタルフィルタ"FIR_x2"の使用方法について

どもです。

昨日は"FIR_x2"について実装の工夫点をいくつかお話しましたが、今回はシミュレーションと実際の使用方法についてまとめていきたいと思います。

audio-diy.hatenablog.com


ディレクトリ構成

ディレクトリ構成は以下の通りとなります。

github.com

FIR_x2のGitHubディレクトリ構成
  • 01_DPRAM_CONT
    シンプルデュアルポートRAMをリングバッファとして機能させるためのコントローラ
  • 02_DATA_BUFFER
    SPRAM_CONTとシンプルデュアルポートRAMを組み合わせて構成したリングバッファ
  • 03_SPROM_CONT
    シングルポートROMから任意のフィルタ係数を出力するためのコントローラ
  • 04_FIR_COEF
    SPROM_CONTとシングルポートROMを組み合わせて構成したFIRフィルタ係数出力部
  • 05_MULT
    DATA_BUFFERから出力されたPCMデータとFIR_COEFから出力されたFIRフィルタ係数を乗算する乗算器
  • 06_ADD
    MULTから出力された乗算結果を積分する加算器
  • 07_FIR_x2
    上記のDPRAM_CONTからADDモジュールを接続して構成したオーバーサンプリングデジタルフィルタのトップモジュール
  • 08_hex
    シンプルデュアルポートRAMとシングルポートROMのデータ初期化用16進数ファイル
  • 09_txt
    シミュレーション用PCMデータ格納ファイル
  • 10_Example
    各種FPGA評価ボード用サンプルプロジェクト
    2023年12月25日現在で「Terasic DE10-Lite」「Terasic DE0-Nano」「Efinix Trion T20 BGA256 Development Kit」「Sipeed Tang Primer 20K」の4種類のボード向けサンプルを保存しています。

    www.terasic.com.tw

    www.terasic.com.tw

    www.efinixinc.com

    wiki.sipeed.com


シミュレーション方法

各モジュールのディレクトリに入ると「(モジュール名).v」と「(モジュール名)_TB.v」が保存されていますので、基本的には各自お持ちのシミュレータで「(モジュール名)_TB.v」を実行すればOKです。

ただし、いくつか注意点がありますのでご注意ください。

  1. シングルポートROM(SPROM.v)とデュアルポートRAM(SDPRAM_SINGLECLK.v)はサンプルプロジェクトで推論されることを確認済ですが、各ベンダーのIPを使ったほうがいろんな面で良いと思います。
  2. FIRフィルタ長は(マスタークロック周波数)÷(サンプリング周波数)で計算してください。
  3. 一部モジュールでは別ディレクトリのモジュールも合わせて呼び出す必要がありますので、実行前に対象のモジュールをよくご確認ください。
  4. 一部モジュールでは「08_hex」や「09_txt」内のファイルを使用しますので、その際はシミュレーションを実行するディレクトリに保存した上で実行してください。
  5. 開発時にQuesta - Intel FPGA Starter Editionで手作業でシミュレーションしたため。vcdファイル保存やシミュレーションの終了タイミングが記述されていません。必要な場合は各自記述ください。

以下にQuesta - Intel FPGA Starter Editionで実行する手順を示しておきます。
ちなみに、シミュレーション実行ファイル(*.do)のPull Request大歓迎です!

  1. 必要なモジュールとテストベンチをプロジェクトにインポートし、コンパイルする。このとき、hexファイルやtxtファイルで必要なものもテストベンチが保存されているフォルダに保存しておく。

    FIR_x2実行時のQuestaプロジェクト
  2. テストベンチファイルを選択し、最適化オプションやその他オプションを設定して実行する。(一部モジュールにはPSLアサーションが記述してあるのでアサーション検証も可能です。)

    テストベンチファイルを選択して実行


  3. 観測したい信号をwaveウィンドウに追加し、Transcriptウィンドウ内にてrunコマンドを入力してシミュレーションを実行する。(実行時間は30万~40万nsあれば十分です。)

    あとは各種検証をお楽しみください。

    波形表示を変更した場合



実機での確認方法

実機の場合はベンダーによりいろいろなお作法があるので一概に「これ!」といった方法はお伝えしにくいですが、

  1. ディレクトリのモジュールをFPGAプロジェクトにインポートする
  2. FIR_x2以外の周辺モジュールを設計し接続する
  3. タイミング制約の記述
  4. ピンアサインの設定
  5. コンパイル

という基本的な流れは変わらないと思います。

以下実機確認の注意点になります。

  1. シングルポートROM(SPROM.v)とデュアルポートRAM(SDPRAM_SINGLECLK.v)はサンプルプロジェクトで推論されることを確認済ですが、各ベンダーのIPを使ったほうがいろんな面で良いと思います。
  2. FIRフィルタ長は(マスタークロック周波数)÷(サンプリング周波数)で計算してください。
  3. 「10_Example」内のサンプルプロジェクトではI2S入力、16bit Right-Justified出力で、Amanero Combo384とPT8211Sを組み合わせて確認しています。

    www.tec-sol.com

    audio-diy.hatenablog.com

    各自使用するDACやオーディオデータ形式に合わせて別途モジュールを準備ください。

サンプルプロジェクトの対応ボードを所有されている方は一度試されるとなんとなくわかるかと思います。


ライセンスについて

そこそこの時間と気合を入れて作ったものですので、ライセンスについてもお話させていただければと思います。

AUDIYが調べた限りでは今回のようなHDLのライセンスはMITライセンスやApacheライセンスで公開されているものが多いようですが、

ということでいろいろ調べた結果、以下のライセンスにたどり着きました。

cern-ohl.web.cern.ch

CERN(欧州原子核研究機構)が制定したライセンスで、ハードウェアのみならずソフトウェアにも適用できるそうです(なぜに原子力関係の機関が・・・・)

https://ohwr.org/project/cernohl/wikis/FAQ#q-my-project-includes-hardware-and-software-how-do-i-make-sure-the-whole-product-is-distributed-together-and-stays-open-source

また、ライセンスの継承についても3段階に区分されていて、制限が強い順に

  1. CERN-OHL-S v2
    ソフトウェアにおけるGPL3に相当する。
    このライセンスによる著作物を使用したプロジェクトはCERN-OHL-S v2でライセンスする必要がある。
    回路等の物理的な著作物にのみ適用可(ソースコード不可)。
  2. CERN-OHL-W v2
    ソフトウェアにおけるLGPL3に相当する。
    このライセンスによる著作物を使用したものはCERN-OHL-W v2またはCERN-OHL-S v2でライセンスする必要がある。
    CERN-OHL-S v2でライセンスする場合は、各自で作成したものについても動作に必要なものは全てCERN-OHL-S v2で公開する必要がある。
    CERN-OHL-W v2でライセンスする場合は、各自で作成したもののライセンスについては問わない(別ライセンスでも良い)。
    ソフトウェアやHDLにも適用可。
  3. CERN-OHL-P v2
    ソフトウェアにおけるApache 2.0ライセンスに相当。
    このライセンスによる著作物を使用したもののライセンスは問わない(CERN-OHLを継承せず別ライセンスを適用しても良い)。

その他「商用利用可」や「保証の要求不可」などは一般的なオープンソースソフトウェアライセンスと類似しています。

ohwr.org

今回はそこそこ時間をかけて開発したことや、個人的にも思い入れがあるのでライセンスの継承だけはしていただきたくCERN-OHL-W v2でライセンスすることにしました。

もし本プロジェクトが何かに使えそうな場合はご一報いただけるとAUDIYが喜びます。w


以上、FIR_x2の中身と使用方法についてでした。

Advent Calenderなのに自分の成果物の発表になってしまいましたが、皆様に教えられるようなHDL関係の知識があるかもビミョーだったので成果物を発表することにしました。

せっかくQuartus付属のシミュレータがModelSimからQuestaに変更になったので、2024年のAdvent Calenderは本記事でも少し触れたアサーション検証についてアウトプットしたいところです。(1年あるのでそれまでに有益な情報が出るかもしれませんね。)

www.paltek.co.jp

 

では皆様、良い年末年始をお過ごしください。

2024年もどうぞよろしくお願いいたします。