前回に引き続き、cocotbによりテストパタンを書いている。 AXIの挙動を真似るのは大変だ。でも、このあたりがうまく攻略できるようになると、例えばISSにPythonのIFを供えれば、ISSとの協調シミュレーションも可能になるのではないか。 あとは、なるべくランダムな要素も入れたいので、Pythonをうまく活用してパタンのカバレッジを上げていきたい。
1. 待ち時間をランダムに設定する
例えば、リクエストが発行されてから、応答するまでの待ち時間をランダムに設定するためには、PythonのRandom関数を使って応答すれば良い。
wait_time = random.randint(0, 10) for i in range(0, wait_time): yield FallingEdge(self.dut.CPU_CLK) if self.dut.IF_MARVALID == 0: raise TestFailure("[NG] IF_MARVILD goes down")
2. 別のモデルを挿入することは可能なのか?
例えば、AXIのマスタはテスト対象そのものだが、スレーブに別のVerilogファイルを含めることは可能だろうか? あるいは、もう一つ上の階層でVerilogで囲んでやる必要があるかもしれない。この辺の調査はあまりできていない。 少なくとも、現在はパタンの環境として、
class tb_mag_ifu(object): def __init__(self, dut, dubug=True): self.dut = dut ... @cocotb.test() def basic_test(dut): """basic_test""" tb = tb_mag_ifu(dut)
まあこの程度しか指定していない。ここでmag_ifuがテスト対象な訳だが、これ以外に例えばAXIメモリなどのモデルを挿入することはできるのだろうか。まだ良く分からない。
3. バグ?関数を定義すると挙動が変わる場合がある
例えば、この二つのコードは同一の意味だと思っているのだがどうだろうか?
@cocotb.coroutine def gen_and_check(self, id): ... wait_time = random.randint(0, 10) for i in range(0, wait_time): yield FallingEdge(self.dut.CPU_CLK) if self.dut.IF_MARVALID == 0: raise TestFailure("[NG] IF_MARVILD goes down") yield RisingEdge(self.dut.CPU_CLK) self.dut.IF_MARREADY <= 1 yield RisingEdge(self.dut.CPU_CLK) ...
def wait_until_marready(self): wait_time = random.randint(0, 10) for i in range(0, wait_time): yield FallingEdge(self.dut.CPU_CLK) if self.dut.IF_MARVALID == 0: raise TestFailure("[NG] IF_MARVILD goes down") yield RisingEdge(self.dut.CPU_CLK) self.dut.IF_MARREADY <= 1 yield RisingEdge(self.dut.CPU_CLK) @cocotb.coroutine def gen_and_check(self, id): ... wait_until_marready()
なんだか良く分からないが、上記の2つでパタンの挙動に違いがでる。というか下記の関数を定義した場合には、パタンが正常に終了してくれなかった。 何だろう?ちょっと調べてみたほうが良さそうだ。
...