aster_ismの工作室

FPGAとかマイコンとか

PythonからIPにデータのアドレスを設定する

FPGAに実装した行列計算IPにnumpyのndarrayのデータが格納されたアドレスを設定したいことがあったのでメモ

ndarrayの場合、実行しているプロセスの仮想アドレスは下記で取得できる

vaddr = a.__array_interface__['data'][0] 

ここ とか ここ をみると、/proc/{pid}/pagemap を見れば物理アドレスが取得できそうなことがわかったので、それを利用する。ほぼ2つめのサイトのpythonコードだが、物理アドレスを返すように修正した。

def get_physaddr(addr, size=8):
    pid = os.getpid()
    offset  = (addr // mmap.PAGESIZE) * size
    with open('/proc/{}/pagemap'.format(pid), 'rb') as f:
        f.seek(offset, 0)
        entry = struct.unpack('Q', f.read(size))[0]
        return (entry & 0x7FFFFFFFFFFFFF) * mmap.PAGESIZE + (addr % mmap.PAGESIZE)

あとは、前回IPをpythonから操作した のと同じように、行列計算IPを設定する。

xadd = fpga.ip('xadd.json')
a = np.random.randint(0, 10, (3, 3), np.uint32)
b = np.random.randint(0, 10, (3, 3), np.uint32)
c = np.random.randint(0, 10, (3, 3), np.uint32)
aa = get_physaddr(a.__array_interface__['data'][0])
ba = get_physaddr(b.__array_interface__['data'][0])
ca = get_physaddr(c.__array_interface__['data'][0])

xadd.px(aa) # 入力1 のアドレス
xadd.py(ba) # 入力2 のアドレス
xadd.pz(ca) # 出力のアドレス
xadd.n(9) # 要素数
xadd.ctrl(1) # 実行
print('{}\n+\n{}\n=\n{}'.format(a, b, c))

実行結果

[[2 7 4]
 [6 5 0]
 [3 5 4]]
+
[[2 7 2]
 [8 3 7]
 [0 6 8]]
=
[[ 4 14  6]
 [14  8  7]
 [ 3 11 12]]