Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

Xilinx xsim で、XSI(Xilinx Simulator Interface)をPythonで使う

はじめに

Google 君で、Xilinx の XSI について調べたら、見つけた

C/RTL Cosimulation with Vivado and Python

github.com

内容

デザイン側は、VHDLなので、テストベンチ側もVHDLに対応するように、信号が9値になっています。

ここ

const char SLV_U=0;
const char SLV_X=1;
const char SLV_0=2;
const char SLV_1=3;
const char SLV_Z=4;
const char SLV_W=5;
const char SLV_L=6;
const char SLV_H=7;
const char SLV_DASH=8;

Python コード

説明のために引用します。

#!/usr/bin/python3.8

import pyxsi
import random

# VHDL uses 1ps timestep by default. This results in a 100 MHz clock.
HALF_PERIOD = 5000

def test_counting():
    xsi = pyxsi.XSI("xsim.dir/widget/xsimk.so", tracefile="counting.wdb")  # Design ライブラリと波形ファイル名を指定

    (old_a, old_b) = (f"{0:016b}", f"{0:016b}")

    for n in range(65535 + 2):
        xsi.set_port_value("clk", "1")    # クロックを Hi
        xsi.run(HALF_PERIOD)             # クロックの半分の時間を進める
        xsi.set_port_value("clk", "0")    # クロックを Low
        xsi.run(HALF_PERIOD)             # クロックの半分の時間を進める

        xsi.set_port_value("a", f"{n & 0xffff:016b}")      # a に値を設定
        xsi.set_port_value("b", f"{n & 0xffff:016b}")      # b に値を設定

        a = xsi.get_port_value("a")                               # a の値を読む 
        b = xsi.get_port_value("b")                              # b の値を読む 
        sum = xsi.get_port_value("sum")                     # sum の値を読む 
        product = xsi.get_port_value("product")         # product の値を読む 

        print(f"old_a {old_a} old_b {old_b} sum {sum} product {product}")

        assert (int(old_a, 2) + int(old_b, 2)) % 2 ** 16 == int(sum, 2)
        assert (int(old_a, 2) * int(old_b, 2)) % 2 ** 32 == int(product, 2)

        (old_a, old_b) = (a, b)


def test_random():
    xsi = pyxsi.XSI("xsim.dir/widget/xsimk.so", tracefile="random.wdb")

    (old_a, old_b) = (f"{0:016b}", f"{0:016b}")

    for n in range(65535):
        xsi.set_port_value("clk", "1")
        xsi.run(HALF_PERIOD)
        xsi.set_port_value("clk", "0")
        xsi.run(HALF_PERIOD)

        xsi.set_port_value("a", f"{random.randint(0, 65535):016b}")
        xsi.set_port_value("b", f"{random.randint(0, 65535):016b}")

        a = xsi.get_port_value("a")
        b = xsi.get_port_value("b")
        sum = xsi.get_port_value("sum")
        product = xsi.get_port_value("product")

        print(f"old_a {old_a} old_b {old_b} sum {sum} product {product}")

        assert (int(old_a, 2) + int(old_b, 2)) % 2 ** 16 == int(sum, 2)
        assert (int(old_a, 2) * int(old_b, 2)) % 2 ** 32 == int(product, 2)

        (old_a, old_b) = (a, b)


if __name__ == "__main__":
    import pytest
    import sys

    pytest.main(sys.argv)

pytest.main にて、test_xxxx を順番にやってくれるってことですね。

おわり

メモっぽいのもありました。

threespeedlogic.com

PythonXilinx xsim の XSI を使った例を見てみました