Ryuz's tech blog

FPGAなどの技術ブログ

産業用カメラを研究開発に用いる場合の課題

はじめに

タイトルの通りなのですが、本来産業用カメラは、製造や流通など産業の現場で活躍する精密かつタフな高品質なカメラであり、現場の要望に応えて進化を繰り返してきたものなのですが、本記事は 本来の用途と違う 研究開発に使う場合の課題について触れてみたいと思います。

産業用カメラについてはこちらなどでも少し触れていますが、どんなものか知らない方もおられると思うので少し有名どころを紹介しておくと、iDSさん、Baslerさん、CISさん、東芝テリーさんとか、このあたりのページに飛ぶと、なんとなくこんなやつと言うのがわかるのではないかと思います。あと高速度カメラだとフォトロンさんなんかもあります。

手元に一個、大学からお借りしたUSBタイプの産業用カメラが手元にありますが、こんなやつです。

USBタイプの産業用カメラ

なぜ画像処理研究に産業用カメラを使うのか

ではなぜ研究開発で普通にパソコンに繋がる一般的な Zoomミーティングなどで使う Web カメラを使わずに産業用カメラを使うケースがあるのでしょうか。

実は Webカメラは本格的な画像処理の研究開発に使うには多くの課題があります。

  • 露光時間/ゲイン/絞りなどの基本項目が設定できないことが多い
  • センサーの緒元が不明、現像処理も不明、あまつさえ勝手に適応制御する
  • 2つのカメラの同期シャッターや、照明との同期もままならない
  • ローリングシャッター歪が課題で、グローバルシャッターが使いたい場合がある
  • BAYER配列が邪魔でモノクロが使いたい場合、赤外が撮りたい場合などがある
  • 高速度撮影/低遅延リアルタイム認識にUSBが遅すぎる

などなど、ちょっとしたアクティブセンシングでもしようものなら役に立たないケースが多数あります。

これらの課題を解決してくれるのが産業用カメラです。

UVCカメラと違い、メーカー専用のAPIを経由してイメージセンサーのかなり細かい設定を行う事が出来、外部トリガの入出力などの機能も有しているものが多いです。

(研究用途での)産業用カメラの課題

高性能な産業用カメラですが、そうはいっても研究用途目的に作られているわけでもないので、課題も残ります。

値段がお高い(笑)

本来の用途を考えれば妥当なのですが、一般的には 10~20万円ぐらい、安い物でも数万円以上、高いものだと100万円を軽く超えてきますので、弱小研究室や個人だと気軽には買えないケースもあるのではないかと思います。

上のお借りしたカメラもメーカー価格で 389ユーロ、日本円を探してみたらこちらで 67,800円でした。これでもかなり安い方だと思います。

FPGAに直結出来ない

こちらでも書きましたが、FPGAに直結できるカメラは少ないです。

アクティブセンシングなどのFPGA制御撮影がしたい場合、複数カメラや照明やロボットをFPGAで操りながら、タイミングを合わせて厳密な撮影制御したいわけですから、これらをFPGAで掌握できないといけません。

一方で、USBタイプ や GigE-Vision などは、ナノ秒オーダーどころかマイクロ秒オーダーの制御をするにはあまりも遅すぎますし、他のインターフェースも高価すぎたり、規格が古く帯域が細かったり、仕様が非公開であったりと課題は多いです。

そしてこうならざるを得ない理由が、次に述べる センサーメーカーのNDA構造にも関連してきます。

センサーメーカーのNDAの問題

このあたりから少し技術とは異なる話になってくるのですが、産業用カメラで使われるイメージセンサーの多くは仕様が一般に公開されていません(そうでないものも少しありますが)。

そこでカメラメーカーはセンサーメーカーとNDA(機密保持契約)を結んでデータを開示してもらいカメラを製造するわけですが、NDAで守られた範囲をユーザーに開示するわけにはいきません。

したがって、カメラメーカーはそれぞれセンサー固有の機能を、産業規格などの一般化されたものに、カメラ内のFPGAなりで変換して外部に出すことになります。この際、物理層や低レイヤーまでは各種産業規格に準じるのですが、カメラに必要な上位のプロトコルは各社ばらばらで、各社独自のAPIを提供しています。ゲイン一つ設定するにも各社で方式が異なり、これもまたベンダーロックになっています。

また、カメラインターフェースもオープンなものもあれど、クローズな規格もあり、中には一定の基準を満たした法人が規格団体の有料会員になって初めて規格書が閲覧できるようなものもあります。

産業カメラの利権構造

結果的に、各社カメラメーカーが用意しているエコシステムを一式購入することになり、これも実質的にベンダーロックになっています。

もちろん、産業分野ではトラブルを起こさず適切なサポートを受けて産業活動を維持するには不可欠な事なのですが、こと研究用途に転用しようとすると困ることになります。特に下手にNDAに踏み込んでしまうと 論文に書けないこと やソースを GitHubに公開できない などの致命的なデメリットを受けかねません。また環境が高価なこと自体が他の人の研究の再現のハードルを上げてしまい研究の広がりを阻害してしまいます。

自作カメラの開発

また、上の絵を見てお気づきかもしれませんが、多くの産業用カメラがその内部にFPGAを内蔵しています。

ですので、当サイトのように「FPGAを活用してリアルタイム画像処理がやりたい」という用途ですと、高価なインターフェースボードとIPを使って、FPGA で変換された信号をまた FPGA でなるべく生の画像信号に戻すというなんとも無駄の多いことをする羽目になります。

信号用のIPも、商用の量産向けのライセンスを想定したものが多いですので、研究用に1個買うだけでも何百万円も払う例は少なくありません。

下記に絵を描きましたがもっとシンプルにやりたいと思ってしまうわけです。

無駄を省いて研究開発に集中したい

そこで私がいま開発しているのが、こちらのグローバルシャッター高速度カメラです。

rtc-lab.com

仕様がデータシートとして公開されているPYTHON300イメージセンサーを使って、KV260 や ZYBO に直結出来るカメラモジュールと言うわけです。このセンサーは Digikeyさんなどでも手に入り、サイズを絞った設定次第で1000fps 以上の高速度撮影もできるグローバルシャッターのカメラなので、研究開発には最適です。

物理層に安価なMIPIコネクタを選んでいるためセンサー側にも Spartan7 FPGA がいますが、こちらの回路図もRTLも公開しておりますので、Spartan-7 も研究対象の回路として扱ってしまえば、かなり理想に近いオープンハードウェアなカメラモジュールと言えます。

昨日、やっと LUT-Network による MNIST の認識が動き始めましたので記念記事として、この記事を書いた次第です。

撮影環境

MNIST認識

おわりに

昨今AIの台頭で、画像処理に挑戦する学生さんや研究者の方も増えているんじゃないかと思います。 この時、普通のZoom会議などで使うUSBカメラで画像処理を行う人が多いのではないかと思います。

一方で、FPGA+カメラ の構成で、普通と違うちょっと違う撮影や制御を行うだけで、「他の誰もやっていない研究」に挑戦しやすくなります。 特にアクティブセンシングや認識結果をさらにフィードバックするようなインタラクションを伴う処理は、パソコン上で PyTorch だけ弄っているのでは絶対に出来ないアルゴリズム研究が次々生まれてきますので、ぜひともいろいろ考えてみて頂ければと思います。

Zynq/ZynqMPのクロス開発環境を構築してみた

はじめに

私はこれまで ZYBO(Zynq-7000) や KV260(ZynqMP) の Linux 環境を活用してセルフコンパイル環境をメインに活用してきました。

Linux では gcc も rust も動きますので、OpenCV などの C++ や Rust などネイティブコンパイラでバージョン依存の強いものも、その場でコンパイルすれば問題が起こりにくいですし、何より FPGA のハードウェアというナマモノを扱うのにセルフ環境からいろいろできるのは便利だったからです。

また、VS Code Remote Development もこれらの環境に ssh で繋ぐだけで使えるため、大変便利でした。

一方で、AI の台頭で Vibe Coding みたいなものが当たり前になってくると、GitHub Copilot などが動くのに慣れ切ってくるわけですが、ZYBO の 512MByte のメモリ環境だと Copilot を有効にすると固まることも増えてきました。

また、4GByte ある KV260 であっても、Copilot と rust-analyzer などを使って、OpenCV や tonic を使うのはさすがに辛くなってきました(主に rust-analyzer が原因?)。

そこで、意を決して、PC からのクロス開発環境の整備に踏み出しました、というのが今回のお話です。

リモートから DeviceTree Overlay を行う FPGA-Server と FPGA-Loader

まず、セルフ開発でない場合に一番面倒なのがこれです。 セルフ開発なら dtb と bitstream を用意して sudo で DeviceTree Overlay できますし、xmutil や dfx-mgr-client を使う手もあります。

root 権限が必要と言うのも何とも面倒で、であれば サービスとして立ち上げてしまえ という安直な解に走ったのが下記の2つのプロジェクトです(PYNQも同じ?)。 このサービスはクロス環境だけでなく、セルフ環境でも便利です。なお、ローカルな利用のみ想定しているので、認証などはまだ入れていません。

github.com

github.com

その際、これまた cargo install もコンパイル時間長いので、バイナリインストールしたいなという事で、 後で述べるクロスコンパイル環境使って GitHub Actions でクロスコンパイルして自動でバイナリファイルをデプロイできるようにしました。

加えて cargo-binstall というとても便利なものを AI に教えてもらい導入しました。

結果、 サーバー側となる ZYBO や KV260 側では

curl -LsSf https://raw.githubusercontent.com/ryuz/jelly-fpga-server/master/binst.sh | sudo bash

とすればサービス登録が完了し、

クライアントを使う PC や ZYBO や KV260 のユーザー環境では

cargo-binstall --git https://github.com/ryuz/jelly-fpga-loader.git jelly-fpga-loader

とすればよいところまできて、サクッとバイナリインストールができるようになりました。

なお、自動デプロイする .github/workflows/release.yml などは、GitHub Copilot がサクッと書いてくれました。AI便利ですね。

ロスコンパイル環境を作る

今回、目指したのは各ボード環境で

apt install libopencv-dev 

して作ったお手軽 OpenCV のネイティブ環境で動くバイナリをクロスコンパイル環境で作る事です。

Python などのインタプリタ言語なら悩むことは無いのですが、FPGA 制御にはまだまだポインタを扱える C++や Rust などのネイティブコードを出力するコンパイラ言語は手放せません。

ここで有効な技術となったのが

です。

まずわかったのが、x86 であっても arm ターゲットボードと同じ Distro で、例えば

dpkg --add-architecture armhf
apt-get update
apt-get install crossbuild-essential-armhf
apt-get install libopencv-dev:armhf

などのようにして、armhf アーキテクチャの libopencv-dev と クロスコンパイラを入れて、おけば、ZYBO で動くバイナリが作れることがわかってきました。

そこで、C++ の為に DevContainer 用の Dokcerイメージ と Rust の cross 用の Docker イメージをそれぞれ用意しました。

さらに、devcontainer.json で、

"features": {
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
},

のようなことをすれば Docke in Docker の機能で DevContainer 内でも cross が使えることがわかりました。

ひとまず、これらを組み合わせて、セルフ環境でもクロス環境でもビルドできる Makefile が書けるようになってきました。

また、bitstream のダウンロードも、セルフ環境でもクロス環境でも先の jelly-fpga-loader で行えますので、あとはビルドしたバイナリを scp なりで送りつけて ssh で実行すればいいことになります。 何らかの方法で、ターゲットボードとクロス開発環境でファイルシステムをマウントしてしまうのも良いかもしれません。

また、Docker イメージは、GitHub Actions でも使えますので、新しいバージョンタグを打つと同時に必要な各種バイナリも自動デプロイする環境が作れてしまうわけで、いろいろ快適になってきたように思います。

おわりに

そのうち、実際のプログラム例が整備出来てきたら、もうちょっとちゃんとした記事にしようと思いますが、ここしばらくこれらに嵌っていたのがようやく落ち着いてきたので、記事にしてみました。

AI 時代も引き続き快適な FPGA 開発環境を維持していければと思います。よきFPGAライフを!

オープンハードウェアの壁

はじめに

ハードウェアの一言でくくってしまうと広すぎますが、個人でも作れる規模の電子基板とかのハードウェアガジェットを想定したお話です。

ここ数十年を経てオープンソースソフトウェア(OSS)というものはだいぶ世間の認知度が上がってきております。特に最近などでは AI の分野での新しい学習モデルであったり、学習データに学習済みパラメータなど、いろいろなものがオープンに公開されるようになってきております。おかげでモデルの改良版の研究や、異なるモデル同士の差分から新しいものを生み出したりなど関連研究がどんどん発展しているのが現状かと思います。

そんな中、FPGAプログラミングはソフトウェアだ、などといきがっている当サイトとしては、もうファブレスでつくれるものは全部ソフトウェア扱いでいいんじゃないか? などと乱暴なことも妄想してみたりもします。

実際、KiCAD で設計したデータを GitHub に上げていたら誰かがクローンを作成して試してみて issue が飛んできたなんてことは私自身も体験しています。

大学などでの研究開発成果を公開する場合も、ちょっと特殊なハードウェア装置を自作した場合、ソースコードだけではなくハードウェアの情報も公開されていないと論文を読んだ人が再現実験しようと思ってもできないわけです。

このソフトウェアでは簡単にできる再現実験であったり、成果の共有であったりを、もっとハードウェア的なところまで広げられればと常々思っていた次第です。

昨今、「3Dプリンタや製造サービスに図面を出せば製造してもらえる」、「基板設計データをアップロードしてクレジットカード決済すれば実装済み基板が送られてくる」といった時代になっているので、これらのものももっとOSS化して、オープンハードウェアにしたいなと思う次第です。

オープンでないハードウェアたち

昔の家電やパソコンは配線図や回路図がついており、町の電気屋さんが修理をしたり、拡張ボードを自分で作ったり自在にできていたそうです。

一方で、昨今はスマホやパソコンはもちろん、カメラやテレビなどの黒物家電も、エアコンや冷蔵庫のような白物家電もそんなものは公開されておらず、ちょっとした修理であれ、自力で分解解析するしかありません。

同様に研究に使うような、産業用カメラなどの機材も内部の回路図など公開されているわけもなく、「製品はブラックボックスとして説明書通りにのみ使ってください」というようになっています。

こういうものがそのまま使える研究なら良いのですが、特殊撮影や特殊センシングがしたい場合、そうもいかないので、公開されているスペックでやりたいことができない場合、自力で分解解析して改造するか、自分で新規に作るかしか選択肢がなくなってしまというなかなか残念なことになってしまいます。

見渡すと我々の周りはクローズなハードウェアだらけであり、買ってきたものをそのまま使い、壊れたらメーカー修理に出すか、買い換えるしかないという、エンジニア的には何とも面白みのないハードウェアが溢れているわけです。

オープンハードウェアをどう定義するか

これがオープンハードウェアだという明確な定義もないかとは思いますので、私なりに下記のように考えてみます。

  • 誰でも買える部品だけで作られていること
  • 設計図やソースコードが一般に公開されていること
  • 公知の情報だけで設計図やソースコードを読みながら理解や改善を行えること
  • 誰でも比較的容易に同じものを作成する方法がある事
  • 改造したものを再公開できるライセンスであること

などでしょうか、例えば電子基板で言えば

  • DigiKey, Mouser, マルツ, RS などで買える部品だけで設計
  • KiCAD の設計や、制御ソフトウェアは GitHub で公開
  • すべての部品はデータシートなり、解析情報なりが公知になっている
  • P版.com、JLCPCB、PCBGOGOなど、個人でも使えるサービスで製造できる事
  • MIT, Apache 2.0, GPL, CC などいろいろなソフトウェアライセンスを参考に適用すればよいように思います

なお、OSS 同様に、商用/非商用とか公開義務の有無とか、いろいろあってよいかとは思います。 ソースがオープンであることが重要で オープンソースハードウェアで OSH とでも呼べばいいのでしょうか(笑)

オープンハードウェアの壁

そこで冒頭のように、「じゃあ、そういうものを自分で作ればいいじゃないか」、となるわけですが、ここにも壁があります。

機密保持契約(NDA)の壁

自作する場合、自分で部品を買い集めて装置を構成していくわけですが、中には「機密保持契約(NDA)を結んだら仕様を教えてあげるよ」なんて部品があったりします。当サイトは画像処理研究が多いのですがイメージセンサーにこの手のものが多いです。

NDAを結ぼうにも大規模な需要が期待できるところじゃないと結んでもらえなかったりもするのですが、それ以前の問題として、NDAを結んでしまうとその情報を使って行った内部設計を容易に公開できなくなってしまいます。

有名大学などが企業との共同研究で凄いセンサーを使った研究論文なんか出したりすることもありますが、多くの場合、共同研究契約の中に機密保持条項が含まれていたりなんかして、どういう効果が得られるかの結果などは華々しく論文書かれていますが、どうやればそれと同じことをできるのかとか、設計図面とかソースコードとかは公開されていなかったりします。想像も含みますが、裏にそういう事情があるケースも結構あるかと思いますので、研究者視点で見ると、研究が広がりを持たないことになり大変もったいなく感じます。

そもそも売ってもらえない壁

バイスを研究開発して販売している側もビジネスですので、当然ながらある程度の需要が見込めるところ以外は相手にできないのです。 実際、零細だと数売れないのにサポート工数的なところで振り回されると死活問題となります。

お問い合わせ段階で、「月産何万個の予定ですか?」なんて確認があったりして、「研究用に5個だけ欲しいんですが」で撃沈したりする話も聞きます。お互い不幸です。

そもそも仮に自分は調達できたとして他の人が容易に手に入れられない部品を使っていると、オープンハードとしては意味をなさなくなってしまいます。

サポートの壁

部品を買うだけなら DigiKey などから買えたりしても、大企業が正規代理店のFAEさんのサポートを受けながら設計するのとは全く違い、公開情報だけからサンプルコードもない中で自力で試行錯誤しながら開発することになりがちです。 もちろん親切に個人事業主や趣味な人のQAに答えてくださるようなところもありますが、そうでないところもあります。

こういう時にとても役立つのがいわゆる製品の分解解析というものです。ネットを探してもいろんな製品を分解したり分析したりしているサイトは多数あるかと思います。

メーカーさんも販売しているものが競合他社に分解解析されることぐらいは織り込み済みなので、本当に隠しておきたいことは製品解析程度では解析できないようにはなっていますが、そうではなくて公開されてる情報だけでは理解が追いつかないのでサンプルが欲しい時って多いのです。 ソフトウェア開発でも「API仕様書だけあっても理解に困るので、サンプルコード欲しい!」ってときありますがまさにそんな感じで、実際の製品を分解解析したりするととても捗るのです。

余談ですがFPGAボードはこういう解析時の計測器としてもとても役立ちます。

お金の壁

これも結構重要でして、ソフトウェアと違って、ハードウェアを開発して公開する側も、それをダウンロードして活用するユーザー側も、どうしても作るのにお金がかかっちゃうのですよね。

これはいくつかOSSと異なる特性を生み出していて

  • 設計が不完全な状態で公開すると、ユーザー側の金銭的損害を発生させてしまう
  • 開発側はなんだかんだでバグが取れるまで試作の繰り返しで浪費してしまう
  • 基板などは各ユーザーが1枚作るより、ある程度まとまった数製造して配布したほうが単価が下がる

などです。

最初の方の話は、「とりあえず何かしら出来たら公開して、ユーザーからバグレポ貰いながら仕上げていく」と言うのがやりにくくなるという、わりと致命的な課題に繋がります。

初期開発費もある程度は寄付とかクラファンみたいなのとかに期待したいところはりますが、まだまだ開発者と受益者でうまく負担分担する仕組みはOSSほど発展していないようには思います。

あとは最後の奴とかは、薄い本を売られている方々が何冊刷るか悩むみたいな話を聞いたことがありますが、それに近い話になりそうです。

これらを緩和するにはとにかく安く作れるよう設計することも重要な気がしております。

オープンハードウェアの事例

世の中にはすでにいろいろなオープンハードウェアはあるのだと思いますが、個人的にはBrilliant Monocleというものを教えて頂いた時が一番衝撃でした。

思わず1つ買ってしまったのですが、これ、ハードウェアの機構の図面も回路図もソフトウェアも全部公開されているんですね。

丁度 GOWIN でカメラやってるときに知って、おんなじチップとカメラが載っていて面食らったのですが、回路図わかっていて JTAG繋いで書き換えできるならなんでもできちゃいそうですよね。

とても素敵なプロジェクトだと思いました。

仕様オープンなハードウェアを開発しつつ、ちゃんと費用回収して次のオープンハードウェアを開発するサイクルが回せれば本当に理想的だと思います。

おわりに

いろいろ書いてしまいましたが、何のことない今取り込んでいるグローバルシャッターMIPIカメラの宣伝記事だったりします(まだ完成してないし、完成するのかも不明なので宣伝もなにもないのですが)。

一応ここに書いたようなことをに挑戦したいなと、なんとか DigiKey や Mouser で買える部品だけで PCBGOGOさんとかに試作してもらいながら、FPGA (KV260) に直結できるグローバルシャッターの高速度撮影カメラ作ろうと頑張っております。

完成したら、BOOTHなどで販売して、開発費の一部でも補填できる程度に回収できると嬉しいなと思いつつ、どうなる事やらと言った感じです。

ただ、副業禁止の会社に勤めていたころはこの「一部でいいから回収して次の開発につぎ込む」すら禁じ手だったので、フリーランスになった今やらずしていつやるのだという感じで頑張っている次第です。

ソフトウェアだけでなく、ハードウェアでも多くの方と成果共有がやりやすいものが作れるといいなと思っております。

今後ともよろしくお願いいたします。

出力から入力する回路

20年前のアイデアの振り返り

例によってネタ記事です。 ちょうど20年ほど前に中二病的に思いついたネタ構造でこのへんから辿れます。とあるきかっけで思い出す機会があったので、改めて面白半分に恥をさらしてみようと思います。

遊星歯車で構成するNANDゲート

この形のアイデア出力から入力が作れないか? という、まあそういう話を夢想しているときに出てきたもので、遊星歯車的な機構を使って、入力側と出力側で力比べできるようになっています。

例えば黄色いレバーを解放した状態で、赤と青を入力として緑を出力とみなすとNANDゲート的にふるまいます。

NAND ゲートがあればどんなロジックでも組めることは有名ですが、この機構では、出力を強い力で 1 にすれば、2つの入力は常にどちらか一方は 0 にならないといけなくなりますし、出力を 0 にすれば入力はどちらも強制的に 1 になります。

なので、このような機構を組み合わせて演算回路を作り、出力側を力持ちの巨人に操作させ、入力側をか弱い小人さんに操作してもらえば、弱い小人さんは、強い巨人の 求める出力になる入力範囲でしか操作できなくなる のではないかという事を考えたわけです。

部分的にこれは正しいのですが、当時まだ二十代でバリバリの中二病だった私は、このNANDゲートで乗算器を組めば一瞬で素因数分解できるんじゃね と、「そんなわけねーだろ!」という妄想に突っ走ったわけです(笑)。

当時知ったエニグマの暗号解読で有名なチューリングボンベが恒等式だという知って影響を受けていたのは言うまでもない話です。

電気回路で再現する

で、当然ながら機械式にそんな複雑なものは組めませんので、電気的な方法を考え始めたわけですが、当然デジタル回路ではこんなことは不可能ですので、自己再帰の筆頭格であるOPアンプの登場です。

  • 力の強い弱いは出力インピーダンスで表現する
  • 常に入出力を対称に、NANDなどの演算を恒等式として満たさないといけないようにする

などの条件で回路を組むこと自体はおそらく可能で、当時 P-Spice 無償版で置ける部品数上限と戦いながら NOT 演算で遊んだのが下記です。

当たり前と言えば当たり前ですが、電気の世界でも力比べは成り立つようですし、演算自体もできそうではあります。

20年前の画像がネット上で掘り起こすと出てくるのが怖いところです(笑)

降下電圧がゼロの理想ダイオードがあれば楽そうですが、まあ頑張れば理想OPアンプだけで出来そうです(笑)。

解なしで爆発するコンピュータ

チューリングボンベも矛盾する入力だとショートするとかしないとか読んだような記憶もありますが忘れ去っています。

例えばこの機構で乗算回路を作った上で出力側に素数を入力しようとしても当然ながら矛盾が生じます。整数と整数を掛け算して素数が生まれることは無いからです。

従って出力に力づくで素数を入れるとかすると

  • 機械式ならレバーが折れて歯車が割れる
  • 電気式ならショートして爆発する

という映画みたいな事が起こる計算機が作れるのではないかと妄想を楽しんでいたわけです。

まあ、矛盾すれば当然レバーは折れるんですが、多分、多項式時間で解けない問題を一瞬で解こうとした場合も折れるんじゃないかなぁ、と。

おわりに

まあ、妄想は妄想として、昨今、誤差逆伝搬法みたいに欲しい出力になるように出力側からあれこれアプローチする手法が生まれて、量子コンピュータのようにいろんな状態を重ね合わせた中から目的の出力を持つものだけを探し出す仕組みであったり、出力から入力を考えるという試みは成功を収めているものも沢山あるのかなと思います。こういった出力側から力を加えて逆算しようというのもやりようによっては面白いかもしれません。

なお、ここで書いた仕組みがなぜ成り立たないのか、かなり昔に中二なりにいろいろ考えて無理だという結論に達した記憶はあるのですが、どうやら当時の私はデスマすぎて「それを書き記すには余暇が足りない」状態だったらしく、今になっては何も思い出せない私なのでした。

FPGAのリセットについて

はじめに

先日 FPGAのリセットについての考察 - Ryuz's tech blog という記事を書きました。

アクセス解析見てみると意外とアクセスが多いページのようで、まじめに普通のFPGAのリセットの話を知りたくて来られた方に申し訳ないので、少しだけそういう話も書いてみます。

リセットの取り扱いはセンシティブな上、微妙に流派や文化もあったりするので、下手なこと書くとマサカリ飛んで来そうではあるのですが、私の知っている範囲のことを FPGAに限定して、なるべく無難に書いてみます。

FPGA でリセットを考えるのは大きく2つ、外部からのリセット信号アサート時(リセットボタンやソフトウェアリセットなど)と、コンフィギュレーション完了時(パワーオン時)の初期化があります。

なお、FPGA のデバイス構造には SRAM 型や Flash 型などがあったりしますが、ここでは基本 SRAM 型の話をします。

SRAM型の FPGA では、動的再構成の為の情報を揮発性のSRAM構造で保持しますので、パワーオン時などに Flash-ROM などからコンフィギュレーションを実施する必要があります。

外部からのリセット信号アサート時

先にリセット信号アサート時の話をします。ASIC設計等ではこちらしかなく、パワーオン時も通常は基板上の電源回路側のパワーオンリセット回路が働き、リセット信号がアサートされますので、「とにかくリセットが来たら初期状態になる事」が必要です。これがそのまま動作中のリセットにも使えます。

この時しばしキーワードとなるのが、「非同期リセット」と、「同期リセット」と、「メタステーブル」です。

メタステーブルについては下記に記事を書いております。

メタステーブルについて考えてみる - Ryuz's tech blog

非同期リセット

SystemVerilog における非同期リセットの書き方は下記の通りで、クロックとリセットのイベントを or で書きます。

always_ff @(posedge clk or negedge reset_n ) begin
   if ( ~reset_n ) begin
      hoge <= リセット値;
   end
   else begin
      // なんか処理
   end
end

非同期リセットの特徴は、クロックが来ていなくても初期化できる ことと、リセット解除に関しては、クロックエッジとの関係次第で、メタステーブルに突入することです。

外部から来るリセット信号は、しばしクロックとはなんのタイミング相関もない非同期信号です。したがって非同期リセットを使う場合でも リセット解除だけはクロック同期させる という事が行われます(AXIバスの aresetn 信号なんかも規格上はそうだったと思います)。

どうしてもクロックなしでも初期化しないといけないシーンは、周辺回路やPLL周りなどで必要になります。 また非同期リセットの ASIC の回路を FPGA に持ってくる場合も使う事になります。

下記が、SystemVerilogでの完全非同期の外部信号を解除だけ同期に変換する記述例です。

外部から来るクロックに同期していないリセットを負論理の reset_n とし、リセット解除のみ clk に同期した reset (正論理)を生成します。

(* ASYNC_REG = "true" *)  logic  [1:0]  sync_ff = 2'b11;
always_ff @(posedge clk or negedge reset_n ) begin
   if ( ~reset_n ) begin
      sync_ff <= 2'b11;
   end
   else begin
      sync_ff <= {sync_ff[0], 1'b0};
   end
end
assign reset = sync_ff[1];

ここで2つ FPGA固有の記述が混ざっていて、本質では無いのですが気になる方もおられると思うので先に注釈しておきます。

  • (* ASYNC_REG = "true" *) は、AMD の Vivado などのシンセサイザで、非同期をうまく扱ってくれる属性
  • logic [1:0] sync_ff = 2'b11; としているのは、コンフィギュレーション完了時の初期値

です。

本題に入ると always_ff のイベントで or negedge reset_n としている部分が、先に述べた非同期リセットの書き方です。

クロックの立ち上がりだけでなく、reset_n が 0 になったら即座に評価するように指示します。このクロックに関わらず if 文の中が実行される書き方が非同期リセットで、実際にFPGA内のFF(フリップフロップ)の非同期リセット端子が利用されるようにコンフィギュレーションされます。

そして sync_ff で2つのFFを駆動しています。これはメタステーブル対策です。フリップフロップの非同期リセットは、リセットがアサートされた際はメタステーブルを起こすことなくリセットされるのですが、リセット解除とクロックエッジが立ち上がった瞬間が重なるとメタステーブルを起こす場合があります。

そこで、sync_ff[0] が、メタステーブル状態になっても、それが収まるまで1クロックサイクル待って sync_ff[1] に取り込むようにすることで対策するわけです。

なお、前述の ASYNC_REG は AMD のシンセサイザの場合、メタステーブルを起こす可能性のあるFF間を、メタステーブルがさらに伝搬することが無いように極力短くルーティングしてくれるように働くとのことです。

なお、万全を期したい場合はFFは2段ではなくさらに複数段入れるとメタステーブルによるMTBFが向上するようです。

同期リセット

SystemVerilog における同期リセットの書き方は下記の通りで、クロックのみがイベントとして書かれます。

always_ff @(posedge clk ) begin
   if ( reset ) begin
      hoge <= リセット値;
   end
   else begin
      // なんか処理
   end
end

多くのFPGAではなるべく同期リセットで記述することが推奨されています。

そして同期リセットの場合は、リセットがクロックに同期していないと、リセット発生時も解除時もメタステーブルを起こす可能性があります。

外部から来るクロックに同期していないリセットを負論理の reset_n とし、 セットも解除も clk に同期した reset (正論理)を生成します。

(* ASYNC_REG = "true" *)  logic  [1:0]  sync_ff = 2'b11;
always_ff @(posedge clk ) begin
   if ( ~reset_n ) begin
      sync_ff <= 2'b11;
   end
   else begin
      sync_ff <= {sync_ff[0], 1'b0};
   end
end
assign reset = sync_ff[1];

こちらはクロックが入らないとリセット入力反映されないという点は注意しておく点です。

FPGA内のFFには通常専用のリセット端子がありますが、非同期で使う場合はそこだけ専用にタイミング解析とタイミング調整を行う必要が出てきて、配置配線の難易度が上がるため、FPGAではすべて同期で使うのが効率の良い結果を得やすいという理由があるようです。

コンフィギュレーション完了時のリセット

こちらは完全にFPGA固有です。一方で、FPGAではリセットボタンなどがついていない基板設計がなされることもあり、コンフィギュレーション完了時以外に「初期化」のタイミングが存在しない使い方もあります。

しかし、しばしそんな場合でも内部のリセット信号をしばらくアサートしたいなんてことがよくあります。

「IP部品の中にもリセットしたままクロックをXXサイクル以上入れて初期化すること」などと書かれているものもあったりするためです。

筆者がよくやるのは下記のような回路です。

logic [7:0]  counter = 8'hff;
logic          reset = 1'b1;
always_ff @(posedge clk) begin
   if ( counter > 0 ) begin
      counter <= counter - 8'd1;
   end
   reset <= (counter > 0);
end

ようするに、FPGAではコンフィギュレーション時に限りレジスタの初期化が出来てしまうのをいいことに、カウントダウンしてリセットを作っているわけです。

もちろんこんな回路を ASIC や CPLD に持っていくとエライことになりますので、FPGA 固有部分は割り切って限定的に扱うのが安全かとは思います。

おわりに

こういうことがいい書き方なのかどうかは正直自信は無いのですが、とりあえず私はこんな感じでリセットを扱っていますというのがご紹介できればと思った次第です。

もっといいリセットの扱い方があるよとか、これだとトラブルが起こるよ、とかあれば情報お寄せいただけると嬉しいです。

追記:FPGAが同期推奨な理由について

AI に聞いたりしているので嘘もあるかもですが、どうやら Dフリップフロップにリセットを付ける場合、非同期か同期かで増加するトランジスタの数が若干違う場合はあるようです。 また、リセットはファンアウトが大きくなりがちですので、リセット解除をLSI全体にタイミングがずれないように行うためにクロックツリーだけでなくリセットツリーも考える必要があるようです。

FPGAの場合残念ながらハードウェア的に提供されているクロックツリーに対して、後から任意の回路にタイミングを合わせるリセットツリーをコンフィギャラブル回路だけで何とかするのは難しいらしく、同期回路として他の信号と同じようにリセットを扱うのが性能を出すには最適解なようです。

そもそもFPGAの場合、LUTやルーティングスイッチなどの比率が大きい為、フリップフロップにリッチなものを置いてもあまりインパクトが無いという事情などもあるようです。

ですので、おそらく ASCI の回路をそのまま FPGA に持ってくると、リセットの観点でも効率が悪く、周波数が下がってしまったりなどがあるのではないかと想像する次第です(リセットの同期/非同期の切り替えが簡単にできる Veryl はこの辺りを意識したものなのだと思います)。

「肩の上の秘書」に思うテクノロジーと人の幸せ

はじめに

今回はコールセンターのたらい回しの話に絡めた、ポエムと言うか駄文回です。

私はテクノロジーというものは人と人とのコミュニケーションを円滑にし、お互いを幸せにすべきものであろうと思っています。

昨今、ChatGPT はじめ、高度なAIの出現で、人と人のコミュニケーションの間に AI を介在させてはどうか、というようなアイデアは多々聞くようになり、しばし技術者同士の雑談の中で星新一の「肩の上の秘書」の話が飛び出したりもしています。

私もかなり昔、ボッコちゃんというの短編集の中の1話としてで読んだ記憶があります。

たしか、セールスマンと客の間でAI的ポジションの肩の上のインコが本音と建て前を変換&通訳(というか取り次ぎ)してくれるというお話だったかと思います。

まさに今のAIを思わせるお話で、星新一さんの先見の明はすごいなと思う次第です。

私事ですが、先日、とある手続きでちょっとしたログイン障害的なトラブルがあり、権限を持ってる人に情報の照会と修正をしてもらわないといけなくなり、問い合わせ窓口が定型対応のチャットしかなく、たらい回しになった後にようやく電話口を案内されて事なきを得た案件がありました。

これに限らないのですが、稀に発生する各種手続きで、そもそもコールセンターの番号に繋がらないとか、音声案内でいろいろ数字を選んで、ようやくオペレーターに転送してもらえたかと思いきや、長時間保留になったりとか、コールバックの電話が出先にいるときに来て書類が確認できなかったとか、そういう事が必要なことは多くはないですが、まあ必要なときはあるわけでして、半日がかりでチャットと電話と並べて時間を浪費することになったりします。

陣内智則さんのコントで 【コント 音声ガイダンス】 というのがありますが、これを見て笑える背景として、「あるある」と思える経験をお持ちの方がそれなりにいらっしゃるのではないかと思います。

1ユーザーとして、「もうちょっと何とかならないの~」と言う思いを抱きつつ、でもこれ対応してくださってるオペレータの方からしても、相手をするお客さんがみんな繋がる前に イライラ度を増幅させる手順を踏んでから 繋いで来てるって嫌じゃないのかな、とか思ってみたわけです。

そういえば、コールセンターの離職率って時々ニュースとかになってるよなと思いつつ、あまり深く考えずに下記を呟いたら、何やらやたらリポストが伸びてしまったりして驚いた次第です。

私の X は主に FPGA 関連などの技術者さん中心のフォロワーさんが多いので、まさかこんな大勢の人に見られるとは思わず、面白おかしく大げさな表現で書いてしまったのも原因かもしれません(汗)

ポストの反応を見て

X は Twitter 時代から基本的に140文字などの短いつぶやきで、前後の背景など省略して要点だけを書きますので、どうしても読む方々それぞれが持っておられるバックグランドによってさまざまな捉え方がなされます。 まさに多様性といった感じで、様々な意見が飛び交う事となり、とても考えさせられました。

皆様のお話を見ていると、どうやらコールセンターに電話してくる人たちには少なくとも3種類ぐらいはおられて

  1. オペレータでないと解決できない問題が発生し、電話しか手段が用意されていないので仕方なく電話している人
  2. 自力解決できないから人間の助けを求めている人(課題の言語化が苦手な人もそれなりに多い???)
  3. 話すことが目的で電話している人(FAQやチャットを用意しても意味がない人)

など、皆様それぞれいろんなケースを頭に思い浮かべられたようです。

私は当初 1 の視点で書いていたので、それ以外を先に思い浮かべる人も多いのに驚いた次第です。

そういえば私の親などはそろそろ高齢で 2 のパターンも増えているようで、「チャットしか窓口が無くて、一生懸命スマホで文字打ってたらタイムアウトした」などと笑い話をしていたのを思い出しました。

パターン 1 の方々は、問題解決までに「しなければならないこと」と「してもらわないといけないこと」が明確になっており、黙々と手順をこなすだけなので、その手順が複雑で億劫であることがストレス増加要因なわけです。

一方で、事業者側からすると、なんとか 2 の人たちをオペレータに繋ぐ前に自力解決に導いてあげたり、3の方々をシャットアウトしたりして、コールセンターの負荷を減らさないと昨今の労働者不足や離職率なども問題のある中、事業が回らなくなる、という事情もまあ想像できるわけです。

パターン3 の方々は正直わたしの想像から一番遠かったのですが、やはり少なからずおられるのでしょう。 実際は課題は抱えておられるのだとは思いますが、字面通り「話す事」が目的だと、むしろ DOCTOR ELIZA 方面のテクノロジーが当てはまりそうには思いました。 コールセンターで働く方々のご苦労に同情を禁じ得ないコメントも多かったです。

余談ですが、私が「怒りゲージMAX」と書いたのは「紳士的でいられるイライラ限界値」ぐらいのつもりだったのですが、これらの事例を想像された方はもうちょっと激昂している状態を思い浮かべた方も多かったのかもしれません。

実際にはこんな簡単な3パターンには収まらないのでしょうが、この3パターンだけでも同じシステムでまとめて対応するの無理じゃないの? とは思うわけで、なるべく初手での振り分けは重要なポイントには思いました。

有効に IT を活用できているのか?

Slack, Discord, Line などの IT技術を使ったコミュニケーション は、時間や空間を超えての人間間のコミュニケーションの効率化に大きく寄与してくれたと考えております。 特に非同期コミュニケーションは、同期コミュニケ-ションである電話やチャットと違い、多くの場合時間効率を高めてくれたように思います。

一方で、どういうわけかこの手の問い合わせは、クリティカルなものほど同期コミュニケーションしか提供されておらず、ユーザー側からすると不満点ではあります。

ただ、私の親がそうであるように、ITツールをうまく使いこなせない層も一定数おられますので、いくつも手段を用意できない場合、なるべく万人を救済しようとするとレガシーな手段に落ち着かざるを得ない面もあるのかもしれません。

そもそも、サポート業務自体が直接的には利益を生まない 構造であるため、致し方ない面はあるのだと思いますが、逆に「ここにお金を払ってもいい」と言う人も一定数はいそうな気もしていて、もう少し何かお互い幸せになれる解は無いものかとは考えてしまうわけです。

役所の手続きのように利益と無関係に公益性の為の仕事であれればよいのでしょうが、やればやるほど利益が減っていく業務として位置づけられてしまうのでなかなか苦しいところなのでしょう。

AIは今後の解決に繋がるのか?

なんだかんだでChatGPTなど大規模言語モデルと呼ばれるような本格的なAIを導入しようとすると、準備も時間がかかり運用にもお金のかかるので、現時点ではほとんどのところで真の意味でのAIの活用はなされていないとは思っております。

ではそういうものを適用すれば解決するのかというとそうでは無かろうとも思っておりますし、逆効果になる事例が容易に頭には浮かぶわけです。

ですが、「うまく使えば、多少の改善はするかも?」という期待も持ってみたりはするわけです。

冒頭の「肩の上の秘書」に戻ると、このお話の重要な点として、セールスマンもお客さんも双方がそれぞれ"自分のAI秘書"を肩に乗せている点があるのではないでしょうか。このようなユーザーサイドにも立つAIエージェント的なものは、一定の効果の可能性がありそうには思います。

  • AIエージェントにやりたいことを依頼(キューイング)しておくことで、同期コミュニケーションを非同期コミュニケーションに変換する
  • あわよくばAIエージェントに閉じて問題を解決する
  • 会話の中から内容と感情成分を分離して、双方の会話ストレスを減らす(まさに星新一)

などでしょうか。

また、顧客の課題解決をするときに、企業側の重要データにアクセスしたり、顧客側も自身の個人情報にアクセスしたり、が必要なケースが少なからずあります。これも AI に権限移譲できないと、結局人間でないと解決できない問題のまま据え置かれます。

  • 企業側のデータにアクセスしたり操作したりできる権限を与えられた企業側AI
  • ユーザの個人情報にアクセスできる権限を与えられたユーザーアプリ側AI
  • お互いの機密を守りあったAI間のインターフェース仕様の策定

などが整備されてくると、少しは改善しないかななどと妄想を膨らませてみたりもした次第でした。

正直、今のAIではまだ難しい気はしていますが、少し未来のAIに関しては否定できない状況にはなってきています。 計算機コストをケチっているところで「あなた(GPT-5) では難しそうなので、GPT-X に代わって!」みたいなやり取りがなされる日が来るかもしれません。スクリプトが引き継げる点だけはAIのメリットかもしれませんね。

ユーザー側も働く側も少ないストレスで気持ちよく活躍できる社会に進展することを祈る次第です。

MIPI-CSI2仕様を調べてみる

はじめに

ご承知の通り MIPI 仕様自体は無償公開あれているような代物ではありませんが、多くの FPGA ベンダーが、無償の IP コアを提供していることもあって、趣味レベルであっても FPGA などで画像取り込みができるような状況になっています。

一方で、それらを駆使して波形の観測などしていると、ある程度は自力で仕様が見えてくる部分があります。

そこで、ここ数年かけて私が独自に解析した結果をブログにまとめようかと思ったのですが、既に、私程度の情報はすべて記事になってることに気が付きました(笑)。 自分用備忘録に以下に張っておきます。

【徹底解説】 MIPIなんて難しくない! 新人がゼロから学ぶMIPI規格 ~ 基礎編 第1回 D-PHY とは? ~ - 半導体事業 - マクニカ

www.macnica.co.jp

docs.amd.com

nahitafu.cocolog-nifty.com

私は RAW 10bit の画像を扱う事が多く 8bit にパッキングされているのを並び替えるのがいつも面倒に思ってますが、よく考えると、4画素が 5バイトになっているわけですが、そのまま 8bit 画像として表示しても 5ピクセル周期で縦線が入るだけで、それっぽい絵になるのはデバッグには便利なのかもしれません(8bit RAW として簡易表示するだけなら 5バイト毎に1バイト捨てればよい?)

CRCECC

これは受信側は計算しなくても合っている前提で無視することもできるのですが、いわゆる普通の CRC-16 やハミング符号のようです。 ただし送信側を作る場合は、受信側次第では計算する必要があるのではないかと思います(送受とも自作する場合はどうでもいいですが)。 今だと AI におねだりすれば普通に計算コードを出力してくれたりもします。

昔データをキャプチャして分析したところ、CRCWikipedia などにもある、普通の CRC-16-CCITT のようでした。

ja.wikipedia.org

ECC が苦労した記憶がありますが、一般論やネットの断片的な情報や、無償のIPでいろいろ生成させたりとかで、ある程度のアタリが付いた記憶があります。

emb.macnica.co.jp

www.marubun.co.jp

https://www.eevblog.com/forum/microcontrollers/calculate-ecc-byte-for-mipi-dsi-header/

最近になって

  • 受信側のテストベンチとして送信信号を作りたい
  • 自作グローバルシャッターカメラでオレオレプロトコル以外にMIPIに寄せたものも試しておきたい

など、送信側も書いてみようという動機があり、ECCはおいておいて、少しコードを書きかけたら GitHub Copilot が勝手に ECC 作る function を吐き出してくるなんてびっくりするような事がありました。

いま改めて、ChatGPT さんに聞いてみると、この手の解析しながら調べながら作ってくと結構面倒なところ、いろいろ出力してくれました。

chatgpt.com

もうなんでも AI で出来てしまう時代ですね。

少し作ってみた

あれこれと試行錯誤中のコードを下記に作成中です。

github.com

もちろん、正規のものではなく、独自解析によるものなので嘘が含まれてる可能性も大いにありますが、「FPGAボードにちょっと MIPI カメラ繋いで遊んでみよう」みたいなホビーな人の参考になれば幸いです。