ZynqでのMIPI Tx/Rxシステム設計 Hardware編
ZynqでのMIPI TxRxシステム設計 Hardware編
はじめに
Xilinxから提供されているIP、MIPI CSI-2 Rx Subsystem / MIPI DSI Tx Subsystemを使ったメモ
環境
FPGA : Xilinx ZCU102 (実機検証無し)
OS : WSL2 Ubuntu20.04
開発環境 : Vivado ML edition 2021.2 Windows版
やりたいこと
MIPI Rx/Tx IPを動かす
参考ドキュメント(Xilinx公式)
MIPI CSI-2 RX Subsystem IP
差動D-phy層で受けてCSI2-RX controllerでVideo timingをAXI Lite Interfaceに変換
Video format bridgeブロックで映像信号をAXI-Streamに変換する
従ってAXI LiteとAXISの二つのbusが存在する
- Timing format(HSync,Vsyncなど)はVitis上でIPDriverから設定する
- Video format(RGB888,YUV844など)はVivado上のIP block designで設定する
- Lane数/通信レートもVivado
MIPI CSI-2とは
主にイメージセンサやディスプレイに使われる差動信号。物理層はD-PHY
MIPI Allianceに加入していないと仕様を確認することはできないが、Webに落ちている仕様書を拝借(下記ドキュメントはNXPのCIS)
SerDesでシリパラ変換して受信する
プロジェクト実装
Vivado Example Designの実装
- VivadoからBoardを「ZCU102」にして空のProjectを作成
- IP Catalog -> MIPI CSI-2 RX Subsystem IPをダブルクリック
- Open Example Designのタブに変更し、Finish
- SourceにIPとしてMIPI CSI-2 RX Subsystemが追加されるので、右クリック
- Create Example Design
- Block Designが完成したら Generate Bitstream
- Export Hardwareで適当なディレクトリにxsaファイルを保存
- 下記ブロックデザインが出来上がる
VitisへのExample Designのimport
- Vitis起動
- Create Application -> platformとして先ほど生成したxsaファイルを選択
- Empty Application -> Finish
- platform.spr選択 -> board support Package -> Drivers
- csirx_0 / mipiciss -> import Examples -> sp701フォルダにチェック -> OK
- xmipi_sp701_example.cを始め、複数ファイルがimportされた
- 実際に使う場合、この後プロジェクトを右クリックしてBuild project
- Run As / Debug As -> Launch Hardware で動くはず
Hardware block
前提
- Zynq Ultrascale+のDisplay PortはPS側
- HDMI/DSI portはPL側
- 今回はHW側でHDMI/DSIのみを使うのでZynq PSへのDisplay入力は不要
Zynq MPSoC
HDMI Display path
DSI Display path
MIPI DSI Tx IP設定
- DSI Tx IPはDCS LPcommand modeに対応しているがRxのみらしい?(Tx不可)
おそらく起動シーケンスでDCS commandをたたくようなデバイスだと別でDCScommandのTXを行えるIPを作る必要があるかも - XilinxのFPGAでMIPIを制御する場合Video Timing Controllerは使わずにAXI-LiteでVsync/Hsync等の信号をZynq側から制御する
- 映像信号はAXI-Streamで制御信号とは別のbusから送る
- DSI Display pathで行っていることは殆どCMOSイメージセンサ入力のCSI-2 Rx Subsystem側で行っていることと同じ
Pin assignment
HPportの中からPinを指定できる。
ここで指定できるHPportはZCU102評価ボードの場合ハードウェア的にはFMCコネクタに繋がっている。
逆にHP Portが出ていない評価ボードの場合どうやって指定するのだろう?(制約ファイル側で指定?
→Zynq Ultrascaleの場合はMIPI Subsystem IPにPin Assignmentが出る模様
手元のZynq-7000だとPin Assignmentタブが無かったため通常通り制約ファイルにピンアサインを行う必要がある。この場合I/FはLP mode:HSUL_12 /HS mode : LVDS_25
下図はZCU102のPin assignment。こんな感じのHPポートが大量にある(Xilinx公式ページより)
ここら辺を参考にするとよさそう
AR# 67963: Zynq UltraScale+ MPSoC ZCU102 評価キット - UG1182 (v1.0) - FMC ピン配置の訂正
制約ファイル
制約ファイルを覗くとPin Assignmentで記述したようにCSI2 Rx/DSI Txのアサインが無い。従って両者に関してはBlock Design内のIPカスタマイズで設定する必要がある。
CISのイニシャライズにI2Cを使っているのと、DSI Display用のGPIOの設定のみ。
I2CのPullupはFPGA側で行っている
#CSI2 Rx Subsystem Related constraints
#Sensor IIC
set_property PULLUP true [get_ports IIC_sensor_scl_io]
set_property PULLUP true [get_ports IIC_sensor_sda_io]
set_property PACKAGE_PIN L15 [get_ports IIC_sensor_scl_io]
set_property PACKAGE_PIN K15 [get_ports IIC_sensor_sda_io]
set_property IOSTANDARD HSUL_12_DCI [get_ports IIC_sensor_scl_io]
set_property IOSTANDARD HSUL_12_DCI [get_ports IIC_sensor_sda_io]
# GPIO Configuration
set_property PACKAGE_PIN M14 [get_ports {GPIO_sensor_tri_o[0]}]
set_property PACKAGE_PIN M10 [get_ports {GPIO_sensor_tri_o[1]}]
set_property PACKAGE_PIN AA12 [get_ports {GPIO_sensor_tri_o[2]}]
set_property IOSTANDARD LVCMOS12 [get_ports {GPIO_sensor_tri_o[*]}]
#DSI GPIO Display
set_property PACKAGE_PIN L12 [get_ports {gpio_display_tri_o[0]}]
set_property PACKAGE_PIN K12 [get_ports {gpio_display_tri_o[1]}]
set_property IOSTANDARD LVCMOS12 [get_ports {gpio_display_tri_o[*]}]
制約ファイルの確認終わり
- Create HDL WrapperしてGenerate Bitstream
- Export Hardware
- HW終了、SWに続く
おわり
間違ってたらコメントください
Discussion