このページでは,exLeafpあるいは他のFPGAボードでexLeafを拡張するサンプルを紹介します.
exLeafがイーサネットポートから受信したUDPパケットデータをUARTでexLeafの外に出力(J5の0番ポートから出力),あるいは逆に,exLeafにUARTで入力(J5の1番ポートから入力)されたUDPパケットデータをUDPパケットにしてイーサネットポートに送信します.サンプルではUDP 1パケットで送れるペイロードデータの長さは最大496バイトに制限されます.
exLeaf-exLeafpの通信方式は,シンプルに1MbpsのUART(8bit,パリティなし,ストップビット1)です.UARTの入力ポートはFPGAのI/Oプルアップ機能でプルアップしています.
exLeafにはロジックが入りきらない,という場合にexLeafpを使ってリソース不足を補なうことができます.また,exLeafをUDPパケット<->UPL変換モジュールとして使うことで,既存のシステムにパソコンとUDP/IPで通信できるポートを簡単に追加するという使い方もできます.
リソース
- exleaf_exleafp_uart_exleaf_20170130.jed – exLeafに書き込むデータ
- exleaf_exleafp_uart_exleafp_20170130.jed – exLeafpに書き込むデータ
ダウンロードして,それぞれexLeafとexLeafpのフラッシュに書き込むことで利用できます.exLeafp側は単純に届いたUDPパケットを送り返す簡単なものですが,ソースコードを参考に自分のモジュールに置き換えることで任意の処理を実装することができるでしょう.
サンプルはexLeafを購入した方は自由にご利用いただけます.ただし,イーツリーズ・ジャパンは,サンプルの利用による損害に対する責任を負うことはできませんのでご注意ください.exLeafの詳細はこちらをご覧ください.
ネットワークパラメタ
- IPアドレス 10.0.0.135 (後述の方法によって動作時に変更可能)
- ネットマスク 255.0.0.0 (後述の方法によって動作時に変更可能)
- デフォルトゲートウェイ 10.0.0.1 (後述の方法によって動作時に変更可能)
- 待ち受けポート 16384番
- MACアドレス 00-1B-1A-EE-00-D7
操作方法
exLeafのJ5の0番と1番を,exLeafpのJ2の1番と0番にそれぞれ接続するとループバック動作を確認できます.単にパソコンから
#!/usr/bin/ruby require "socket" udp = UDPSocket.open() dest = "10.0.0.135" dest = ARGV[0] if ARGV.size > 0 sockaddr = Socket.pack_sockaddr_in(16384, dest) msg = [0xABADCAFE, 0x05050505, 0xa0a0a0a0, 0x01010101, 0x02020202, 0x03030303, 0x04040404, 0x05050505, 0x06060606, 0x07070707, 0x08080808, 0x09090909, 0x0a0a0a0a, 0x0b0b0b0b, 0x0c0c0c0c, 0x0d0d0d0d, 0x0e0e0e0e, 0x0f0f0f0f, 0xDEADBEAF, ].pack('N*') p msg udp.send(msg, 0, sockaddr) p udp.recv(2048); udp.close
というようなスクリプトを実行すれば,パソコン→exLeaf→exLeafp→exLeaf→パソコンとデータが送り返される様子を確認することができます.
ネットワークパラメタを変更する
IPアドレス,ネットマスク,デフォルトゲートウェイを動作中に書き換えることができます.ただし,設定値はFPGA内のレジスタに格納されるだけですので,電源再投入時には,デフォルトのパラメタに戻ります.
変更するには,IPアドレス,ネットマスク,デフォルトゲートウェイをペイロードとするUDPパケットを16385番ポートに送信してください.
たとえば,
#!/usr/bin/ruby require "socket" udp = UDPSocket.open() sockaddr = Socket.pack_sockaddr_in(16385, "10.0.0.135") d = [0xc0, 0xa8, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00, 0xc0, 0xa8, 0x00, 0x01] msg = d.pack('C*') udp.send(msg, 0, sockaddr) udp.close
というパケットを送信すれば,ノードのIPアドレス,ネットマスク,デフォルトゲートウェイを192.168.0.2, 255.255.255.0,192.168.0.1にセットすることができます.
exLeafを制御するexLeafp側の回路の作り方
exLeafを制御するexLeafp側の回路では,適切なUPLパケットを入出力することでUDPパケットの送受信ができます.まずUPLフォーマットを紹介します.また,サンプルを元にexLeafp側の回路の作り方を説明します.サンプルプロジェクトに含まれるuart_to_upl16およびupl16_to_uartを使うと比較的簡単にexLeafを外から制御するモジュールを実装できます.
UPLフォーマット
exLeafとexLeafp間でやりとりされるUPLパケットフォーマットは次の通りです.送信元・送信側IPアドレス,ポート番号,パケットタイプ,長さに続いてユーザが自由にデータを与えることができます(最大496バイト).
exLeafから出力されるデータ
0〜1バイト | これから送られるデータのバイト数 |
2〜5バイト | 送信元のIPアドレス |
6〜9バイト | 送信先のIPアドレス(exLeafに設定されているIPアドレスのはず) |
10〜11バイト | 送信元のポート番号 |
12〜13バイト | 送信先のポート番号(exLeafが待ち受ける16384番のはず) |
14〜15バイト | 予約 |
16〜17バイト | データ本体のバイト数 |
18〜513バイト | データ |
exLeafに入力すべきデータ
0〜1バイト | これから送られるデータのバイト数 |
2〜5バイト | 送信元のIPアドレス(ホストに送り返しを期待するならexLeafに設定されているIPアドレスを指定する) |
6〜9バイト | 送信先のIPアドレス |
10〜11バイト | 送信元のポート番号(ホストに送り返しを期待するならexLeafが待ち受ける16384番にする) |
12〜13バイト | 送信先のポート番号 |
14〜15バイト | パケットタイプとして17(0x0011)を指定する |
16〜17バイト | データ本体のバイト数 |
18〜513バイト | データ |
exLeafp側のサンプル回路の構成
exLeafp側のサンプル回路のモジュール構成は次の図のようになっています.
このサンプル回路では,uart_to_upl16はUARTを介してexLeafから出てくるデータをデータ幅16bitのUPLに組み立て,逆に,upl16_to_uartは16bit幅のUPLで与えらられたデータをシリアル化しUARTに出力します.
UPLはイーツリーズ・ジャパンのIPコアで利用している,モジュール同士のデータ授受をシリアライズ化したパケットとしてやり取りする方式です.詳細はUPLとはを参照してください.uart_to_upl16およびupl16_to_uartではストローブ付きのUPLを利用しています.
サンプルは単に送られてきたパケットを送り返すだけですが,user process内でデータを加工することで所望のアプリケーションに仕立てることができるでしょう.また,必ずしもパケットを送り返す必要はなく,uart_to_upl16だけを使って受け取ったパケットを処理するだけのモジュールや,upl16_to_uartだけを使ってexLeafにパケット送信させるだけのモジュールを作ることもできます.
exLeafp以外のボードでexLeafを使う
exLeafp以外のボードでもexLeafを使ってUDPパケットをやりとりすることができます.たとえば,次のプロジェクト一式はDigilent社のCMOD-A7にexLeafを接続する例です.
PMODの1番をUARTのTX,2番をRXに割り当てています.
ちなみに,FPGAである必要もありません.1MbpsでのUART入出力ができるのであればマイコンやパソコンに接続することもできます.