1.1.1. Altera® AXI4 Memory-Mapped Specification Support
1.1.2. Altera® AXI4 Memory-Mapped BFM Components
1.1.3. Altera® AXI4 Memory-Mapped Supported Features
1.1.4. Altera® AXI4 Memory-Mapped BFM SystemVerilog Packages
1.1.5. Altera® AXI4 Memory-Mapped BFM Supported Flows
1.1.6. Altera® AXI4 Memory-Mapped BFM Supported Simulators
1.3.1. Altera® AXI4 Memory-Mapped Manager BFM Configuration
1.3.2. Altera® AXI4 Memory-Mapped Manager BFM Interface
1.3.3. Altera® AXI4 Memory-Mapped Subordinate BFM Configuration
1.3.4. Altera® AXI4 Memory-Mapped Subordinate BFM Interface
1.3.5. Altera® AXI4-Lite Memory-Mapped Manager BFM Configuration
1.3.6. Altera® AXI4-Lite Memory-Mapped Manager BFM Interface
1.3.7. Altera® AXI4-Lite Memory-Mapped Subordinate BFM Configuration
1.3.8. Altera® AXI4-Lite Memory-Mapped Subordinate BFM Interface
1.3.9. Altera® AXI4 Memory-Mapped Inline Monitor Configuration
1.3.10. Altera® AXI4 Inline Monitor Interface
1.4.1. Using the Altera® AXI4 Memory-Mapped Manager BFM Flow
1.4.2. Using the Altera® AXI4 Memory-Mapped Subordinate BFM Flow
1.4.3. Using the Altera® AXI4 Memory-Mapped Monitor BFM Flow
1.4.4. Altera® AXI4 Memory-Mapped Manager RTL Implementation Example
1.4.5. Altera® AXI4 Memory-Mapped Manager Platform Designer BFM Implementation Example
1.5.1. Altera® AXI4 Memory-Mapped BFM Configuration API
1.5.2. Altera® AXI4 Memory-Mapped BFM Reset API
1.5.3. Altera® AXI4 Memory-Mapped Manager Transaction Creation API
1.5.4. Altera® AXI4 Memory-Mapped Subordinate Transaction Creation API
1.5.5. Altera® AXI4 Memory-Mapped Transaction Configuration API
1.5.6. Altera® AXI4 Memory-Mapped BFM Transaction Execution API
1.5.7. Altera® AXI4 Memory-Mapped Host Memory API
2.5.1.2.1. Class Axi4StreamBytes
2.5.1.2.2. Data Members in Axi4StreamBytes Class
2.5.1.2.3. Methods in Axi4StreamBytes Class
2.5.1.2.4. Class Axi4StreamBytesData
2.5.1.2.5. Methods in Axi4StreamBytesData Class
2.5.1.2.6. Class Axi4StreamBytesPosition
2.5.1.2.7. Methods in Axi4StreamBytesPosition Class
2.5.1.2.8. Class Axi4StreamBytesNull
2.5.1.2.9. Methods in Axi4StreamBytesNull Class
2.5.1.2.10. Class Axi4StreamBytesDataError
2.5.1.2.11. Data Members in Axi4StreamBytesDataError Class
2.5.1.2.12. Methods in Class Axi4StreamBytesDataError
2.5.1.2.13. Class Axi4StreamBytesPositionError
2.5.1.2.14. Data Members in Class Axi4StreamBytesPositionError
2.5.1.2.15. Methods in Class Axi4StreamBytesPositionError
2.5.1.2.16. Class Axi4StreamBytesNullError
2.5.1.2.17. Data Members in Class Axi4StreamBytesNullError
2.5.1.2.18. Methods in Class Axi4StreamBytesNullError
2.4.4. Altera® AXI4 Streaming BFM RTL Example
The following top_tb.sv testbench example is uses the axi4st_tx_bfm and axi4st_rx_bfm BFMs generated from the Quartus® Prime Pro Edition software IP Catalog. For more information about creating simulation models and setup scripts, refer to Quartus® Prime Pro Edition User Guide: Third-party Simulation.
// top_tb.sv
`timescale 1 ps / 1 ps
import altera_lnsim_ver.axi4_stream_bfm_types_pkg::*;
import altera_lnsim_ver.axi4_stream_bytes_class_pkg::*;
import altera_lnsim_ver.axi4_stream_transfer_class_pkg::*;
import altera_lnsim_ver.axi4_stream_packet_class_pkg::*;
// For simplicity, defining hierarchical names of manager and subordinate BFMs
//<bfm IP inst>.axi4_stream_bfm_<transmitter/receiver>_0.axi4_stream_<tx/rx>_bfm
`define bfm_tx tx_bfm_inst.axi4_stream_bfm_transmitter_0.axi4_stream_tx_bfm
`define bfm_rx rx_bfm_inst.axi4_stream_bfm_receiver_0.axi4_stream_rx_bfm
module top_tb ();
localparam real CLK_PERIOD = 10;
localparam DATA_BUS_WIDTH = 4; // Data Bus Width in bytes.
localparam TID_WIDTH = 8; // TID width in bits.
localparam TDEST_WIDTH = 4; // TDEST width in bits.
localparam TUSER_WIDTH = 12; // TUSER width in bits.
bit clk, rstn;
wire [0:0] tvalid;
wire [0:0] tlast;
wire [ 0:0] tready;
wire [DATA_BUS_WIDTH*8-1:0] tdata;
wire [DATA_BUS_WIDTH-1:0] tstrb;
wire [DATA_BUS_WIDTH-1:0] tkeep;
wire [TID_WIDTH-1:0] tid;
wire [TUSER_WIDTH*DATA_BUS_WIDTH-1:0] tuser;
wire [TDEST_WIDTH-1:0] tdest;
// start toggling clock
always begin
#(CLK_PERIOD/2) clk = ~clk;
end
initial begin
rstn = 0;
#10;
repeat (1) @(posedge clk);
rstn = 1;
end
axi_st_tx_bfm tx_bfm_inst (
.tvalid (tvalid), // output, width = 1, altera_axi4_stream_transmit_if.tvalid
.tlast (tlast), // output, width = 1, .tlast
.tready (tready), // input, width = 1, .tready
.tdata (tdata), // output, width = 32, .tdata
.tstrb (tstrb), // output, width = 4, .tstrb
.tkeep (tkeep), // output, width = 4, .tkeep
.tid (tid), // output, width = 8, .tid
.tuser (tuser), // output, width = 48, .tuser
.tdest (tdest), // output, width = 4, .tdest
.clk (clk), // input, width = 1, clock_sink.clk
.rst_n (rstn) // input, width = 1, reset_sink.reset_n
);
axi_st_rx_bfm rx_bfm_inst (
.tvalid (tvalid),// input, width = 1, altera_axi4_stream_receive_if.tvalid
.tlast (tlast), // input, width = 1, .tlast
.tready (tready),// output, width = 1, .tready
.tdata (tdata), // input, width = 32, .tdata
.tstrb (tstrb), // input, width = 4, .tstrb
.tkeep (tkeep), // input, width = 4, .tkeep
.tid (tid), // input, width = 8, .tid
.tuser (tuser), // input, width = 48, .tuser
.tdest (tdest), // input, width = 4, .tdest
.clk (clk), // input, width = 1, clock_sink.clk
.rst_n (rstn) // input, width = 1, reset_sink.reset_n
);
// Transfers
Axi4StreamTransfer#(.AXI4_STREAMING_DATA_BUS_WIDTH(DATA_BUS_WIDTH),
.AXI4_STREAMING_TID_WIDTH(TID_WIDTH),
.AXI4_STREAMING_TDEST_WIDTH(TDEST_WIDTH),
.AXI4_STREAMING_TUSER_WIDTH(TUSER_WIDTH)) tx_tr, rx_tr;
// Transfer Queues - Stores tx and rx transfers for comparison at simulation end
Axi4StreamTransfer#(.AXI4_STREAMING_DATA_BUS_WIDTH(DATA_BUS_WIDTH),
.AXI4_STREAMING_TID_WIDTH(TID_WIDTH),
.AXI4_STREAMING_TDEST_WIDTH(TDEST_WIDTH),
.AXI4_STREAMING_TUSER_WIDTH(TUSER_WIDTH)) trq_tx[$], trq_rx[$]; //History Queue
// Packet handles.
Axi4StreamPacket#(.AXI4_STREAMING_DATA_BUS_WIDTH(DATA_BUS_WIDTH),
.AXI4_STREAMING_TID_WIDTH(TID_WIDTH),
.AXI4_STREAMING_TDEST_WIDTH(TDEST_WIDTH),
.AXI4_STREAMING_TUSER_WIDTH(TUSER_WIDTH)) p;
byte_t byte_buf [];
Axi4StreamBytes#(TUSER_WIDTH) asb; //Super Class
Axi4StreamBytesData#(TUSER_WIDTH) asbd;
Axi4StreamBytesPosition#(TUSER_WIDTH) asbp;
Axi4StreamBytesNull#(TUSER_WIDTH) asbn;
Axi4StreamBytes#(TUSER_WIDTH) ba[]; // Byte array
Axi4StreamBytes#(TUSER_WIDTH) q[$]; // Queue
int i;
string message;
string formatted_number;
initial begin
// Clear transfer queues
trq_tx.delete();
trq_rx.delete();
// Transfer 1 - load from buffer
byte_buf = '{8'h00, 8'h11, 8'h22, 8'h33, 8'h44, 8'h55, 8'h66, 8'h77,
8'h88, 8'h99, 8'hAA, 8'hBB, 8'hCC, 8'hDD, 8'hEE, 8'hFF,
8'h10, 8'h11, 8'h12, 8'h13, 8'h14, 8'h45, 8'h16, 8'h17,
8'h18, 8'h19, 8'h1A, 8'h1B, 8'h1C, 8'h1D, 8'h1E, 8'h1F};
tx_tr = new();
tx_tr.set_payload_from_data(byte_buf);
tx_tr.set_gap(5);
tx_tr.print_payload();
// Load transfer into queue to compare at end of simulation
trq_tx.push_back(tx_tr);
// Create Packet
p = new();
// Add transfer to packet
p.add_transfer_to_packet(tx_tr);
// Transfer 2 - load using queue
q.delete();
asbd = new(8'h00);
asbd.set_tuser_value('hbcd);
asb = asbd;
q.push_back(asb);
asbd = new(8'h11);
asb = asbd;
q.push_back(asb);
asbd = new(8'h22);
asb = asbd;
q.push_back(asb);
asbd = new(8'h33);
asb = asbd;
q.push_back(asb);
asbd = new(8'h44);
asbd.set_tuser_value('h123);
asb = asbd;
q.push_back(asb);
asbd = new(8'h55);
asbd.set_tuser_value('h456);
asb = asbd;
q.push_back(asb);
asbd = new(8'h66);
asbd.set_tuser_value('h789);
asb = asbd;
q.push_back(asb);
asbd = new(8'h77);
asbd.set_tuser_value('habc);
asb = asbd;
q.push_back(asb);
asbd = new(8'h11);
asb = asbd;
q.push_back(asb);
asbd = new(8'h12);
asb = asbd;
q.push_back(asb);
asbd = new(8'h13);
asb = asbd;
q.push_back(asb);
asbd = new(8'h14);
asb = asbd;
q.push_back(asb);
//Position Byte
asbp = new();
asb = asbp;
q.push_back(asb);
//Position Byte
asbn = new();
asb = asbn;
q.push_back(asb);
asbd = new(8'h17);
asb = asbd;
q.push_back(asb);
asbd = new(8'h18);
asbd.set_tuser_value(0);
asb = asbd;
q.push_back(asb);
// transfer queue to byte array
ba = new[q.size()];
for(i=0; i<q.size(); i++)
begin
ba[i] = q[i];
end
tx_tr = new();
tx_tr.set_tdest('h7);
tx_tr.set_tid('h14);
tx_tr.set_payload_from_bytes(ba);
tx_tr.print_transfer_short();
// Load transfer into queue to compare at end of simulation
trq_tx.push_back(tx_tr);
// Add transfer to packet
p.add_transfer_to_packet(tx_tr);
// Transmit packet
`bfm_tx.transmit_bfm.put_packet_for_transmit(p);
while (`bfm_rx.receive_bfm.get_number_of_transfers_in_queue() != trq_tx.size())
begin
@(posedge clk);
end
formatted_number = num_formatter(`bfm_rx.receive_bfm.get_number_of_transfers_in_queue(), "d");
message = {" Number of transfers in receive queue: ", formatted_number};
$display("*****");
$display("%s", message);
$display("*****");
while (`bfm_rx.receive_bfm.transfer_available())
begin
rx_tr = `bfm_rx.receive_bfm.get_transfer_from_receive();
rx_tr.print_transfer_long();
trq_rx.push_back(rx_tr);
end
foreach(trq_rx[i])
begin
if (trq_rx[i].is_not_equal(trq_tx[i]))
begin
formatted_number = num_formatter(i, "d");
message = {" Transaction Failed: ", formatted_number};
$display("*****");
$display("%s", message);
$display("*****");
end
else
begin
formatted_number = num_formatter(i, "d");
message = {" Transaction Passed: ", formatted_number};
$display("*****");
$display("%s", message);
$display("*****");
end
end
end
endmodule
The following shows the simulation output from this example:
Figure 14. Streaming BFM RTL Example Simulation Output