exLeafp(あるいは他のFPGAボード)でexLeafを拡張する

このページでは,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のフラッシュに書き込むことで利用できます.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入出力ができるのであればマイコンやパソコンに接続することもできます.