動作環境
- Windows 10 Pro (21H1)
- Vivado 2019.1
関連
- 2021-12-02 AXI Verification IPを使う (AXI4LITE)
- PG277 AXI4-Stream Verification IP v1.0
手順の概要
- Vivadoでプロジェクトを新規作成
- Block Designを「sys」という名前で作成する
- Tools > Create and Package New IP ... > Create a new AXI4 peripheral
- InterfaceをStreamに変更
- myip_0をBlock Designに追加する
- AXI4-Stream Verification IPを追加する
- INTERFACE MODEをMASTERに変更
- TDATA WIDTH(BYTES)を4に変更
- IPに合わせてこうした
- 名前はaxi_vip_0にしている (System Verilogの記述に合わせて)
-
agent = new("master vip agent", dut.sys_i.axi_vip_0.inst.IF);
だけが関係する?
-
- aclk, aresetnのピンをMake Externalする (名前をこのようにする)
- axi_vip_0とmyip_0を接続する
- Create HDL Wrapperをする
- Simulation Sourcesにtb.svを作成する
- Run Simulationをする
- 見たいピンを波形に足す
- m_axi_wlast, m_axi_wvalid, m_axi_wready, m_axi_wdata[31:0]
- s00_axi_wdata[31:0], s00_axi_rready, s00_axi_rvalid
Block Design
テストベンチ (System Verilog)
https://qiita.com/tethys_seesaa/items/9d4c00212d9ea79b1497
の実装をベースとしてAXI4Streamに書き換えした。
tb.sv
`timescale 1ns/1ps
//import axi_vip_v1_0_1_pkg::*;
//import axi_vip_pkg::*;
import axi4stream_vip_pkg::*;
//import sys_axi_vip_0_0_pkg::*;
import sys_axi4stream_vip_0_0_pkg::*;
module tb();
localparam int LP_CLK_PERI = 100;
localparam int LP_RST_PERI = 777;
// DUT instance
logic aresetn, aclk;
sys_wrapper dut(.*);
task rst_gen();
aresetn = '0;
#(LP_RST_PERI);
aresetn = '1;
endtask
task clk_gen();
aclk = '0;
forever #(LP_CLK_PERI/2) aclk = ~aclk;
endtask
task clk_dly(int n);
repeat(n) @(posedge aclk);
endtask
// VIP decreation
// sys_axi_vip_0_0_mst_t agent;
sys_axi4stream_vip_0_0_mst_t agent;
task init_agent();
agent = new("master vip agent", dut.sys_i.axi_vip_0.inst.IF);
agent.start_master();
endtask
// Transaction method
task wr_tran();
// for axi
//axi_transaction wr_transaction;
//wr_transaction = agent.wr_driver.create_transaction( "write transaction with randomization");
//WR_TRANSACTION_FAIL: assert(wr_transaction.randomize());
//agent.wr_driver.send(wr_transaction);
// for axi4stream
axi4stream_transaction wr_transaction;
wr_transaction = agent.driver.create_transaction("write transaction"); // wr_driver=>driver
WR_TRANSACTION_FAIL: assert(wr_transaction.randomize());
agent.driver.send(wr_transaction); // wr_driver=>driver
endtask
task rd_tran();
// for axi
//axi_transaction rd_transaction;
//rd_transaction = agent.rd_driver.create_transaction("read transaction with randomization");
//RD_TRANSACTION_FAIL_1a:assert(rd_transaction.randomize());
//agent.rd_driver.send(rd_transaction);
// for axi4stream
axi4stream_transaction rd_transaction;
rd_transaction = agent.driver.create_transaction("read transaction with randomization"); // rd_driver=>driver
RD_TRANSACTION_FAIL_1a:assert(rd_transaction.randomize());
agent.driver.send(rd_transaction); // rd_driver=>driver
endtask
// Testscenario
initial begin
fork
init_agent();
clk_gen();
rst_gen();
join_none
clk_dly(100);
wr_tran();
clk_dly(100);
//rd_tran();
wr_tran();
clk_dly(100);
$finish(2);
end
endmodule
- Streamなので、wr_tran()とrd_tran()を対にはせずにwr_tran()だけに
- wr_tran()をもう一回実施
- axiからaxi4stream変更時に「wr_driver」「rd_driver」はともに「driver」に変わったようだ
Run Simulation
波形を見る時は「Zoom Fit」を実行して全体表示してから見たい部分を見る。
以下の例では一部を拡大したもの。
m_axis_tdataの値がそのままs00_axis_tdataに入っている。
tvalid=1, tready=1のときが有効なデータ (参考: 後述のFPGAの部屋さんの記載)。
wr_tran()を5回実施した例。m_axis_tvalidが5回1になっている。
関連
- AXI4-Stream のお勉強 @ FPGAの部屋さん
- https://marsee101.blog.fc2.com/blog-entry-2454.html
- 信号の説明が書かれている
- 必須とオプションの記載、など
-
AXI4-Stream を試す by 筑波大学 武内修様
- AXI4 StreamのMaster IPなので、これと接続するのはAXI4-Stream VIP (Slave)になる?