2014年03月31日

SVIMonプラグイン機能の紹介

開発部ブログでは、過去にオムニビジョン社のOV7670を接続したりFX3の高速化についての記事を掲載したりと、弊社の主力製品であるSVI-06ボードを使用していろいろな検証をしてきました。これまでは主にハードウェアが中心の内容となっていました。
そこで今回は、SVI-06に標準で付属しています画像を表示するためのソフトウェアとそのソフトウェアの便利機能であるプラグイン機能について書いてみたいと思います。

SVI-06ボードでキャプチャーしたイメージセンサ等のデータは、USB3.0経由により、PC上のSVI-06専用ソフトウェアである「SVIMon」により画像データとしてリアルタイムに確認することができます。この、「SVIMon」はSVI-06ボードを購入いただくと標準で付属しています。


SVIMonImage.jpg

「SVIMon」の機能としては、
・画像データの表示・保存
・入力画像のYUVやRGB等のカラーフォーマット対応
・Sync Mode/Data Input Timingの変更設定
・プラグイン機構の搭載と便利プラグインの提供

といった機能があります。画像データ表示や保存などの機能は基本機能としてご活用いただいておりますが、弊社として便利なのに一番活用されていないと感じているのがプラグイン機能です。
そこで今回はこのプラグイン機能について説明をします。

プラグインとは、「アプリケーションソフトウェアの機能を拡張するために追加するプログラムの一種」(Wikipedia調べ)です。SVIMonにはプラグインを動作させることができる機構が搭載されており、その仕組みを利用すれば、拡張プログラムをだれでも簡単に作ることができます。

SVIMonにも弊社で作成したプラグインがいくつか付属しています。主なプラグインとして下記のようなものを提供しています。


<Easy Logic Analyzer(簡易ロジックアナライザ)>
Easy-Logic-Analyzer.jpg
datファイル(弊社独自形式ファイル)のデータをLogicAnalyzerのような波形として簡易的な表示をすることが可能です。


<Vector Scope(ベクタースコープ)>
Vector-Scope_Image.jpg
画面上にCb、Crをベクトル化して描画します


<Waveform(波形モニター)>
Waveform_Image.jpg
画像の指定した1ライン(HまたはV)を取得して、YUV・RGBの各値を表示します。



これらのプラグインは多くのお客様にご使用いただいております。それぞれのプラグインの機能の詳細については、ソフトウェアに付属の説明書をお読みください。

この機構を利用してお客様ご自身でもプラグインを開発することができます。初めて開発する場合でも、Visual Studio2008で作成したサンプルプロジェクトを提供しておりますので、必要な部分のみ追加することで簡易に開発を行うことができます。
また、アクセスできるデータもSVI-06ボードから取得したデータにそのままアクセスすることができますので、カメラの画サイズやカメラフレームレート、また画像データを使用したプラグインを作成することができます。

SVI-06ボードからの画像データを表示するアプリケーション「SVIMon」とプラグインについて説明をしました。ご興味ありましたら弊社までお問い合わせください。

ソフトウェアではプラグインは一般的な機能になりつつあると思いますが、ハードウェアにもこのような、ハードウェアの機能を拡張するプログラムを追加できたらいいなと思いませんか? 

実は、それができる仕組みがSVI-06にはあります。
そこで次回から、FPGA版プラグイン機能ともいえるFPGA動的再配置についてブログを書いていきたいと思います。
posted by デベマネ at 14:06| Comment(0) | SVシリーズ

2014年03月24日

NEC主催の高位合成セミナー参加レポート

1ヶ月以上までになりますが、2014年2月5日(水)に行われた、NEC主催の高位合成セミナー『CyberWorkBench Forum 2014』に参加してきましたので、そのときの様子などをレポートいたします。

CyberWorkBench Forum 2014の各セッションのアジェンダは次の通りです。
1.CyberWorkBenchの適用領域拡大と今後の機能拡張の紹介(NEC)
2.CWB画像ライブラリのご紹介とその応用開発事例(荻原電機株式会社)
3.CyberWorkBenchを活用したはやぶさ2画像認識FPGA開発事例(NECエンジニアリング株式会社)
4.CyberWorkBenchによる大規模ASICへのフルチップ動作合成適用事例について(株式会社アドバンテスト)


各セッションごとに思ったことなどをまとめておきます。

<CyberWorkBenchの適用領域拡大と今後の機能拡張の紹介>
主題はCyberWorkBenchをメインとしているようでしたが、おおむね高位合成についての説明が多かったと思います。「ソフトウェアプログラムからハードウェア記述を合成する高位合成技術」をもとにプレゼンテーション資料が作成されているように思います。

高位合成を活用した事例としては、NICカードにFPGAを搭載し、ネットワークストリームから特徴量計算を行うことによりる低遅延処理の事例等を取り上げていました。とはいえ実際にデモでそれらを見ることはできず話を聞くにとどまりました。どうも開発段階とのことでした。

また、高位合成を活用するメリットとのひとつとして紹介していたのは、モータ制御の例です。
PWM制御であれば、C言語で記述した場合は2行で済むので制御処理を素直に書くことができることを紹介していました。(HDL記述であれば2行ではすまないということでした。)

そのほか、CyberWorkBenchを活用した場合、Cソース上でタイミングデバックが行えることや、HW/SWを同時にデバック(協調検証)が行えることを強調していました。

全体的な感想としては、具体的な活用事例は紹介されておりませんでしたのでそこがもう少しあればよかったかと思いました。


<CWB画像ライブラリのご紹介とその応用開発事例>
このセッションでは、CyberWorkBenchで開発した画像処理IPの紹介がメインでした。
この画像処理IPとCyberWorkBenchを活用して、カメラ画像を4×4のスナップショットとして外部モニターに描画させるという処理を、インターンシップ生に作成してもらったところ、1週間で行えたとのことが報告されていました。

CyberWorkBenchを使うところから1週間ということなので、FPGA開発の初心者でも早く開発が行える事例といえるかもしれません。


<CyberWorkBenchを活用したはやぶさ2画像認識FPGA開発事例>
CyberWorkBenchを活用した事例として、はやぶさ2での画像処理部のFPGA開発を取り上げて詳細に説明をされていました。この事例の概要は次の通りでした。

初代はやぶさでは画像処理をASICで行っていたとのことですが、はやぶさ2では様々な要因からFPGAに開発を実施することになりました。ただし、初号機の設計を継承して確実な開発を行うとの方針も合わせて示されたため、移植を検討することになったようです。
幸い、C言語で記述した画像処理アルゴリズムがあったので、CyberWorkBenchを活用してFPGAを作成する方針で進めることができたとのことでした。

まず、対象のFPGAデバイスに実装可能かどうかの検証を行ったそうです。CyberWorkBenchで画像処理を含む部分をざっと作成して合成を行うと、回路規模(LUTsとレジスタ)を見積もってもらえる機能があり、その指標から判断を行ったとのことです。

そうしてデバイスの見積もりを行いつつ、画像処理アルゴリズムと外部のメモリーをつなぐ部分などを一部新規開発して実装を行ったとのことです。当然ですが画像処理アルゴリズムには一切手を入れていないので、新規開発部分のみをデバックすればよく効率的な開発を行えたとのことを言っていました。

また、CとHDL記述の比較としてC言語のほうがHDLの記述と比べてコード記述量を1/4にできたとのことでした。また、C言語のほうが可読性も上がるとの指摘をされていました。

このようなことから、設計・検証工数の短縮を実現し、コスト削減も行えたとのことでした。CyberWorkBenchの効果が端的にわかるとても良い事例紹介だと思いました。

<CyberWorkBenchによる大規模ASICへのフルチップ動作合成適用事例について>
最後のセッションでは、FPGAの開発ではなく、ASICの開発にCyberWorkBenchを活用している事例の紹介でした。CyberWorkBenchで設計したASICとしては4チップの回路規模が紹介されていました。
開発したチップの回路規模としては、1stチップが2000万ゲートでしたが、4thチップでは18000万ゲートの物まで開発を積み重ねてきているとのことでした。

そもそもCyberWorkBenchを導入することで、コード記述量を1/5に削減したい意向があったとのことですが、単純にそこまで削減するには至らず、CyberWorkBenchおよびCyberWorkBenchに合わせた設計自動化ツールを使ってコード記述量を減らしているとのことでした。また、高位合成設計仕様書作成ガイドラインやBDL記述ガイドラインなどのガイドラインを充実させ、主に初心者に向けたドキュメントの充実を図っているとのことでした。
その結果として回路規模は大きくなっているものの、手動のコード記述量や工数を削減できているとのことでした。ただし、当初想定の1/5までは届いていないので今後も試作を行っていくとのことでした。

このセッションでは、良い点と悪い点を明確に発表されており、聞いている人からするとなるほどと考えさせられる内容でした。


以上、高位合成のセミナーに参加してきました。C言語でFPGAが作成できるのであればソフトウェアエンジニアにとっても、ハードウェア設計者の意図を理解したコミュニケーションが取れるようになるのでそれだけでも効果は高いのではと思いました。そもそも、ソフトウェアとハードウェアというエンジニアの垣根を大幅に低くでき、相互に意思疎通が図れるようになる技術なのではないかと感じました。
posted by デベマネ at 15:28| Comment(0) | 日記

2014年03月17日

FX3のI2Cを使ってADV7511の設定をしよう〜I2C通信編〜


初回の「FX3のI2Cを使ってADV7511の設定をしよう〜I2C設定編〜」ではFX3でI2C通信をするための仕組みを組み込みました。
2回目の「FX3のI2Cを使ってADV7511の設定をしよう〜ADV7511設定編〜」ではADV7511の設定を行いました。

前回までの記事でADV7511の初期設定は終了しましたが、今回はSVM-03とUSB接続されたPCから、ADV7511のレジスタ値を読み書きしてみたいと思います。

PC上で使用するアプリケーションはサイプレス社のFX3用SDKにあるcontrol centerを使用します。
SDKをインストールしたディレクトリーの
「\cypress\EZ-USB FX3 SDK\(バージョン番号)\bin\CyControl.exe」
にcontrol centerの実行ファイルがありますのでそれを起動しておきます。

次から、I2Cを書き込む場合と読み込みの場合に分けて、設定方法を説明します。


<ADV7511のレジスタに値を書き込む場合>
control centerの画面が下記になります。その画面上に操作手順を説明するための番号と枠線をつけております。

i2C-send.jpg


以降画面上の番号に沿って操作方法を説明していきます。

@「Cypress USB BulkloopExample」→「Configuration 1」→「Control endpoint(0x00)」を選択します。

A「Data Transfers」タブを選択します。

BDirection、ReqType、Targetを下記の値にそれぞれ設定します。
Direction:Out
ReqType:Vendor
Target:Device

CReqCode、wIndexを下記の値に設定します。ReqCodeは書き込みの場合は「0xba」を指定します。wIndexは書き込み先サブアドレスの設定を行います。(画面は0x00afをサブアドレスに指定している例です。)
ReqCode:0xba
wIndex:0x00af

Dレジスタに書き込む値を「Data to send(Hex)」テキストボックスに入力します。この時「Bytes to Transfer」の値も自動で変化しますが正しくない場合には値を修正します。

E赤枠の「Transfer Date」ボタンを押します。

すると、下の大きなテキストボックスに「CONTROL OUT transfer completed」と表示されれはI2Cの設定がFX3から行われたことになります。

書き込みが正しくできているかどうかは書き込み対象のレジスタの値を読み込んで確認をしてください。

<ADV7511のレジスタから値を読み込む場合>

i2c-Receive.jpg


@「Cypress USB BulkloopExample」→「Configuration 1」→「Control endpoint(0x00)」を選択します。

A「Data Transfers」タブを選択します。

BDirection、ReqType、Targetを下記の値にそれぞれ設定します。
Direction:In
ReqType:Vendor
Target:Device

CReqCode、wIndexを下記の値に設定します。ReqCodeは書き込みの場合は「0xbb」を指定します。wIndexは書き込み先サブアドレスの設定を行います。(画面は0x0043をサブアドレスに指定している例です。)
ReqCode:0xbb
wIndex:0x0043

D「Bytes to Transfer」に読み込みたいバイト数を指定します。開始サブアドレスはwIndexで指定したアドレスになります。(画面は2バイト読み込みの例になります。)

E赤枠の「Transfer Date」ボタンを押します。

下のテキストボックスに指定したサブアドレスのレジスタの値が表示されます。

いかがでしたでしょうか。FX3のI2C機能を利用してADV7511のレジスタの読み書きを行いました。
これにて、FX3を利用してのADV7511の設定のブログ記事は完結です。

また、HDMIモニターボードSVM-03に興味ございましたらSVM-03のページも合わせてご覧ください。

※なおここに掲載したADV7511の設定およびソースコードは製品版のSVM-03では使用してはおりません。ただし、画像が正しく表示されることやI2Cが設定できることを確認しています。あらかじめご了承ください。
posted by デベマネ at 14:48| Comment(0) | FX3/ADV7511

2014年03月10日

FX3のI2Cを使ってADV7511の設定をしよう〜ADV7511設定編〜

前回の「FX3のI2Cを使ってADV7511の設定をしよう〜I2C設定編〜」ではFX3でI2C通信をするための仕組みを組み込みましたので、今回はその仕組みを
使用してADV7511の初期設定をしたいと思います。

まず初めに、前回I2C通信を組み込んだSDKのサンプルにadv7511_initとadv7511_Setup_16bitYuv422toYuv422_registersを追加していきます。

void
adv7511_init(void)
{
// adv7511_Setup_16bitYuv422toYuv422の初期化実施
adv7511_Setup_16bitYuv422toYuv422_registers();

}

void adv7511_Setup_16bitYuv422toYuv422_registers(void)
{
uint16_t wSubAddr;
uint16_t i, t1;

// ADV7511その他初期化処理
for(i=0;;i++){
if(ADV7511_Setup_16bitYuv422toYuv422[i][0] == 0x0 ) break; /* terminate*/
wSubAddr = (uint16_t)ADV7511_Setup_16bitYuv422toYuv422[i][1];
CyFxUsbI2cTransfer (wSubAddr, 0x7a, 1, (uint8_t *)&ADV7511_Setup_16bitYuv422toYuv422[i][2], CyFalse);
}
}


adv7511_init(void)はadv7511_Setup_16bitYuv422toYuv422_registers()を呼び出すための関数になっています。ADV7511_Setup_16bitYuv422toYuv422という配列に格納された設定値を1要素ずつ、ADV7511のレジスタに設定していきます(1バイトずつI2Cによりレジスタ設定を行います)。

では、次ににADV7511の設定値を記載した配列を準備します。

const uint8_t nv_adv7511_start[][3] = {
/*slv, sub, data*/
{0x39, 0x41, 0x10}, // Main Power Up
{0x39, 0x98, 0x03}, // Must be set to0x03 for proper operation
{0x39, 0x9a, 0xe0}, // Must be set to 0b1110000
{0x39, 0x9c, 0x30}, // Must be set to 0x30 for proper operation
{0x39, 0x9d, 0x61}, // Must be set to 0b01[1:0] for proper operation
{0x39, 0xa2, 0xa4}, // Must be set to 0xA4 for proper operation
{0x39, 0xa3, 0xa4}, // Must be set to 0xA4 for proper operation
{0x39, 0xe0, 0xd0}, // Must be set to 0xD0 for proper operation
{0x39, 0xf9, 0x00}, // This should be set to a non-conflicting I2C address (set to 0x00)

{0x39, 0x43, 0x7e}, //EDID Memory Address
{0x39, 0x45, 0x70}, //Packet Memory I2C Map Address
{0x39, 0xe1, 0x78}, //CEC Map Address
{0x39, 0x40, 0x00}, // packet update Disable
{0x39, 0x44, 0x01}, // packet update Disable
{0x39, 0xe2, 0x01}, // CEC(周辺機器と通信できる機能) power down

// link config
{0x39, 0x15, 0x01}, // I2S sampling freq. 44.1KHz, Input format 16b, 4:2:2, YCrCb
{0x39, 0x16, 0xb9}, // Output format 4:2:2, 8-bit, style 2, DDR falling, Output color space = YCrCb

{0x39, 0x17, 0x02}, // 16:9 Aspect Ratio
{0x39, 0x18, 0x46}, // Color Space Conversion(CSC) disable
{0x39, 0x40, 0x80}, // Enable GC Packet
{0x39, 0x48, 0x00}, // Video Input Bus Reverse= Normal Bus Order,Video Input Justification is Evenly Distributed
{0x39, 0xd0, 0x3c}, // Disable DDR Negative Edge CLK Delay, DDR Negative Edge CLK Delay=Nodelay,
// Sync Pulse Select=no sync pulse,sync adjustment then DE generation
{0x39, 0xba, 0x00}, // External HDCP EEPROM,Clock Delay=-1.2ns,Don't Show AKSV,HDCP Ri standard
{0x39, 0xde, 0x10}, // Normal TMDS Clock

// SetConfig
{0x39, 0xaf, 0x06}, // HDCP disabled, HDMI mode

// avi infoFrame Setting
{0x39, 0x55, 0x20}, // Y1Y0 (AVI InfoFrame) = YCbCr 422
{0x39, 0x56, 0x28}, // Picture Aspect Ratio = 16:9 Active Format Aspect Ratio = Same as Aspect Ratio
{0x39, 0x44, 0x78}, // avi infoFrame Packet Enable

{0x00, 0x00, 0x00} // I2C終了フラグ
};


※ここで紹介しているADV7511の設定はLinuxドライバ等の設定を参考に弊社で作成したものです。弊社環境での動作確認はしております。また、SVM-03ではこの設定を利用していません。

1080p、60fpsのYUV形式でのカラーバー画像をFPGAからADV7511に送っていますのでその設定になります。
まず初めに、Main Power UpフラグをOnにします。その後ADV7511は決まりとして、パワーアップ後にいくつかのレジスタを設定する必要があります。それが、{0x39, 0x98, 0x03}から{0x39, 0xf9, 0x00}の値になります。
それ以降は出力の設定や仕様に合わせてレジスタ値を設定します。詳細はADV7511のハードウェアユーザーガイドおよびプログラミングガイドをご確認ください。

またレジスタ設定についてはFPGAの部屋の下記の記事が参考になります。(弊社でも参考にさせていただきました。ありがとうございます!)併せてご覧ください。
ZedBoardでHDMI出力10(ADV7511のピクセル入力レジスタ設定)
またFPGAの部屋のブログ内検索で「ADV7511」で検索すると関連記事が表示されます。


最後に今追加した設定をFX3起動時に行えるようにAppThread_Entry関数にadv7511_init関数を追記します。

このように設定して、USBケーブルでPCとボードを接続すると、HDMIモニターにカラーバーが表示されます。(USBケーブル接続時にFX3の電源がONとなります。)


adv7511-colorbar-Image.jpg


※注意:ADV7511の設定は接続先モニターやADV7511に入力する信号等により変更する必要があります。この設定を適用しても動作しない場合がありますのでご了承ください。

ADV7511を設定しカラーバーが表示されました。これでADV7511の初期設定まで完了しました。
次回は、cypress社から提供されているcontrol centerアプリを使用して、I2C通信を行ってみたいと思います。

タグ:FX3 ADV7511
posted by デベマネ at 12:20| Comment(0) | FX3/ADV7511

2014年03月03日

FX3のI2Cを使ってADV7511の設定をしよう〜I2C設定編〜

新製品として、HDMI対応モニターボードSVM-03を発表しました。このSVM-03はカメラなどの入力画像をHDMIモニターに直接出力することができます。詳細はSVM-03のページをご確認ください。
SVM-03にはHDMIに出力するためにADV7511を使用しています。また、USB3.0接続用のFX3も搭載しています。そこで、今回はFX3のI2C機能を使用して、ADV7511の初期設定を行いたいと思います。

FX3でI2Cを行うために使用するFX3のSDKサンプルは、「serialif_examples」フォルダにある「cyfxusbi2cregmode」です。このサンプルはI2Cをレジスターモードで行うサンプルになっています。また、コントロールセンターを使用してI2Cの設定コマンドを送受信することができるようになっています。

ADV7511の設定は、FX3の起動時に1度呼出す形として実装を行います。本来はエラー処理なども検討して実装を行う必要がありますが、説明のため簡略化しています。また、その後はPCからのI2C送受信が行えるようになります。

システム構成は次のようになります。


I2C-ADV7511-sysConf.jpg

SVM-03はUSB3.0経由でPCと接続します。このPCは次の2つの役割を果たします。
・USBポートからの給電(SVM-03はUSB給電のみ対応。ACアダプタ無し)
・PC上のcontrol center からI2Cの送受信を行う

また、HDMIから正しく映像が出力されていることを確認するために、HDMI接続にてモニターに接続をしています。
モニターに出力される画像はこのボードに搭載されているFPGA(Spartan-6 XC6SLX15)にて1080p、60fpsのYUV形式でのカラーバー画像を作成しています。

では、I2Cを行うサンプルソースを眺めていきましょう。
「cyfxusbi2cregmode」フォルダ内の「cyfxusbi2cregmode.c」を開きます。このファイルにI2Cの初期化や送信などの処理を行うコードが書かれています。

このサンプルの基本的な動作フローを説明します。
まず、FX3起動後に既定の処理を行い、スレッドを起動します。起動したスレットでは次の動作を行います。(既定の処理については以前掲載した「FX3プログラミング Hello Worldを出してみよう」のブログをご覧ください。)


adv7511-I2C-Flow.jpg


初めにI2Cの初期化を行い、I2Cが使用できるようにします。次にADV7511のレジスタの初期化設定をI2Cにて行います。その後は、control centerからのI2CのRead/Writeの指令があるまで待機をします。これが一連の動作フローとなります。

今回はADV7511とFX3でI2C通信するためにSDKのソースを一部変更しましたが、変更した関数に絞って変更内容を紹介いたします。

<CyFxUSBSetupCB関数>
主な変更は次の箇所です。
1.関数内で指定されているローカル変数の名前を、「wIndex」→「wSubAddr」に変更します。これは、わかりやすさのためにそのようにしています。

2.switch (bRequest)の条件CY_FX_RQT_I2C_EEPROM_WRITEとCY_FX_RQT_I2C_EEPROM_READにあるi2cAddrの値を「i2cAddr = 0xA0 | ((wValue & 0x0007) << 1);」→「i2cAddr = 0x7A;」に変更。これは、ADV7511のメインレジスターアドレスになります。

<CyFxUsbI2cTransfer関数>
主な変更箇所は次の箇所です
1.「pageCount」と「glI2cPageSize」を使用して繰り返しI2Cを行う作りとなっていますが、不要なので関連する記載を削除します。

2.I2CのRead部分(if (isRead)がTrueの時に呼び出される部分)を以下のように修正します。
preamble.length = 3; // preambleバッファサイズ
preamble.buffer[0] = devAddr; // Slave address.
preamble.buffer[1] = (uint8_t)(byteAddress & 0xFF); // Sub address
preamble.buffer[2] = (devAddr | 0x01); // Read用Slave address.
preamble.ctrlMask = 0x0002; // Read用アドレス格納位置
status = CyU3PI2cReceiveBytes (&preamble, buffer, byteCount, 0);
if (status != CY_U3P_SUCCESS)
{
    return status;
}

3.I2CのWrite部分(if (isRead)がTrueの時に呼び出される部分)を以下のように修正します。

preamble.length = 2; // preambleバッファサイズ
preamble.buffer[0] = devAddr; // Slave address
preamble.buffer[1] = (uint8_t)(byteAddress & 0xFF); // Sub address
preamble.ctrlMask = 0x0000; // Read用アドレス格納位置
status = CyU3PI2cTransmitBytes (&preamble, buffer, byteCount, 0);

preamble.ctrlMaskに関しては、Read用アドレスが格納されたpreamble bufferの配列位置を指定するもののようです。2バイトアドレッシングモード時には、0x04を、1バイトアドレッシングモード時には0x02を指定して読み込み(CyU3PI2cReceiveBytes)を行います。当然Writeではこの値は0x00となるようです。
詳細はCypressの開発者コミュニティのフォーラム「I2C preamble question」の回答に「FX3_I2C_DETAILS.zip」があります。
PDFファイルに詳細が記載されておりますのでご確認ください。

次回は、ADV7511の初期設定について記載をしていきます。
タグ:FX3 I2C ADV7511
posted by デベマネ at 12:37| Comment(0) | FX3/ADV7511