FPGAを使ったSoC的なシステムのメリットの一つに、お仕着せのマイコンと違って、好きなだけペリフェラルコントローラを搭載できることがありますね。たとえばMicroBlazeに5つのUARTポートをぶらさげることもできます。
…という、とてもシンプルな例ですが、まあ、やってみました、という話です。リソース一式はaxi_timer_test.zipから。ターゲットはAvnetのMicroBoardです.
システム構成
こんな感じです。ぽちぽちとUART IPコアのインスタンスを並べればOKです。AXI Liteのバスで、全部MicroBlazeにぶら下げています。前回のタイマ割り込みを使うサンプルに付け足してみました。
合成してソフトウェアを書く
あとは、いつものように合成してSDKにエクスポート、CでアクセスすればOK.ここで一つ注意。XPSプロジェクトにつぎたしつぎたし開発している場合、XPSプロジェクトにおける変更が生成済BSPには反映されないことに気を付けないといけません。今回の例であれば、uartliteコアを5つ生成したとしても、それより前に生成されたBSPではXPAR_AXI_UARTLITE_0_BASEADDRは使用できません。
volatile unsigned int * uart0_tx = (unsigned int*)(XPAR_AXI_UARTLITE_0_BASEADDR+4); volatile unsigned int * uart1_tx = (unsigned int*)(XPAR_AXI_UARTLITE_1_BASEADDR+4); volatile unsigned int * uart2_tx = (unsigned int*)(XPAR_AXI_UARTLITE_2_BASEADDR+4); volatile unsigned int * uart3_tx = (unsigned int*)(XPAR_AXI_UARTLITE_3_BASEADDR+4); volatile unsigned int * uart4_tx = (unsigned int*)(XPAR_AXI_UARTLITE_4_BASEADDR+4); for(;;){ *uart0_tx = 0x00000030; *uart1_tx = 0x00000031; *uart2_tx = 0x00000032; *uart3_tx = 0x00000033; *uart4_tx = 0x00000034; volatile unsigned int i; for(i = 0; i < 1000000; i++){ ; } }
UARTLITEのIPコアのドキュメント(PG142)を見るとわかるのですが、非常にシンプルなつくりで、TX FIFO(ベースレジスタ+4)に値を書くとそのままシリアル出力してくれる、という仕組みです。
ちなみに、受信はステータスレジスタ(ベースレジスタ+8)を読んで、RX FIFO(ベースレジスタ+0)を読めばよいです。簡単ですね。
サンプルプロジェクトでは各シリアルポートをPMODの端子に割り振っいます.たとえばUSB-UARTモジュールへのソースポートをつなぎかえることで,それぞれのポートから、’0’、’1’、..、’4’という文字が出力できていることが確認できます。
で?
というわけで、複数のペリフェラルがつなげられますよ、ということなのですが、それらをMicroBlaze上のソフトウェアで協調させるのはなかなかに面倒なようにも思います。リアルタイムOSみたいなシステムを使えばいいのかな?
もっとも、そもそも細粒度並列処理が実現可能なFPGA上にシステムを構築しているのだから、複数のデバイスでの協調が必要なのであればそれらをまとめる制御レイヤくらいまではソフトウェアじゃなくてハードウェアでやってしまうというのも手かもしれません。
コメント