cocotbでAXIの接続をシミュレーションしてみる。まずはAXIのランダム応答のモデルを作ってみる。超適当だけど、ARチャネルとRチャネルのモデルがランダム時間で応答するようにして、それをマスターが正しく受けとることができていれば成功とすれば良い。
always @ (posedge AXI_CLK) begin if (AXI_RESET == 1'b1) begin SARREADY <= 1'b0; end else begin if (SARVALID) begin for (rand_ar = 0; rand_ar < ($random % 10); rand_ar = rand_ar + 1) begin @(posedge AXI_CLK); end SARREADY <= 1'b1; ar_rcv_cnt = ar_rcv_cnt + 1; @(posedge AXI_CLK); SARREADY <= 1'b0; end end // else: !if(AXI_RESET == 1'b1) end // always @ (posedge AXI_CLK) always @ (posedge AXI_CLK) begin if (AXI_RESET == 1'b1) begin SRVALID <= 1'b0; end else begin if (r_rcv_cnt != ar_rcv_cnt) begin for (rand_r = 0; rand_r < ($random % 10); rand_r = rand_r + 1) begin @(posedge AXI_CLK); end SRVALID <= 1'b1; while (SRREADY != 1'b1) begin @(posedge AXI_CLK); end for (burst_i = 0; burst_i < 4; burst_i = burst_i + 1) begin SRDATA[ 31: 0] <= $random; SRDATA[ 63:32] <= $random; SRDATA[ 95:64] <= $random; SRDATA[127:96] <= $random; @(posedge AXI_CLK); end SRVALID <= 1'b0; r_rcv_cnt = r_rcv_cnt + 1; end // if (r_rcv_cnt != ar_rcv_cnt) end // else: !if(AXI_RESET == 1'b1) end // always @ (posedge AXI_CLK)
cocotbのテストパタンとしては以下のように記述してみた。MARVALIDが立ち上がるか、適当な時間までにMARREADYが帰ってくるか。 その後適当な時間までにMRVALIDが帰ってくるかもチェックしなければならない。
counter = 0 while (int(dut.IF_MARVALID) == 0 and counter < MAX_WAIT): counter = counter + 1; yield Timer(clock_period) dut.log.info("counter=%d" % counter) if counter == 100: raise TestFailure ("IF_MARVALID is not assert") elif int(dut.IF_MARVALID) != 1: raise TestFailure ("After 2-cycle later, IF_MARVALID is not asserted, IF_MARVALID=%d" % dut.IF_MARVALID) else: dut.log.info("Ok!") counter = 0 while (int(dut.IF_MARREADY) == 0 and counter < MAX_WAIT): counter = counter + 1; yield Timer(clock_period) if counter == MAX_WAIT: yield Timer(1000) raise TestFailure ("After IF_MARREADY is not responded") elif int(dut.IF_MARREADY) == 1 and int(dut.IF_MARVALID) == 1: dut.log.info("Ok!") else: yield Timer(1000) raise TestFailure ("After IF_MARVALID=%d and IF_MARREADY=%d should be both valid" % (dut.IF_MARVALID, dut.IF_MARREADY))
パタンが乱雑になってきたので、関数化して整理するかな。