fpga: lib: Add synthesizable AXI4-Stream SV components
Components are connected together with AxiStreamIfc. Some features
include:
(1) Add bytes to the start of a packet
(2) Remove bytes from a packet
(3) Wrappers for some older components
a. fifo - buffer but imediately pass a packet
b. packet_gate - buffer and hold till end of packet
c. width_conv - cross clock domains and change width of axi bus
The AxiStreamIf was moved from PkgAxiStreamBfm to its own file. It can
be used to connect to ports with continuous assignment.
AxiStreamPacketIf must be used procedurally but allows the following
new methods:
- reached_packet_byte - notify when tdata contains a paritcular byte
- get_packet_byte/get_packet_field - extract a byte or field from axi
- put_packet_byte/put_packet_field - overwrite a byte or field onto axi
Original-commit: c3bca6c87700054c96320de119a58f6a688dbd5a
This commit is contained in:
@@ -0,0 +1,594 @@
|
||||
//
|
||||
// Copyright 2020 Ettus Research, A National Instruments Brand
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Interface: AxiStreamIf
|
||||
// Description:
|
||||
// AXI4-Stream is an ARM standard for representing streams or packets in
|
||||
// a design. For more information on the spec see:
|
||||
// https://static.docs.arm.com/ihi0051/a/IHI0051A_amba4_axi4_stream_v1_0_protocol_spec.pdf
|
||||
//
|
||||
// The interface contains methods for
|
||||
// (1) Monitoring progress of a packet
|
||||
// (2) Extracting fields from a packet
|
||||
// (3) Overwriting fields in a packet
|
||||
//
|
||||
// Parameters:
|
||||
// - DATA_WIDTH - Width of tdata on AXI4S bus
|
||||
// - USER_WIDTH - Width of tuser on AXI4S bus
|
||||
// - MAX_PACKET_BYTES - Maximum number of bytes between tlast. If 0, no
|
||||
// word_count resources are added.
|
||||
// - TDATA - use tData if 1
|
||||
// - TUSER - use tUser if 1
|
||||
// - TKEEP - use tKeep if 1
|
||||
// - TLAST - use tLast if 1
|
||||
//
|
||||
// Some Historic USRP code uses tuser without tkeep frequently.
|
||||
// The usage of tuser varies, here are some examples:
|
||||
// (1) Instead of using tkeep, user can encode number of valid bytes in a word
|
||||
// (2) The MSB can indicate an FCS failure from the MAC
|
||||
// (3) Header information is passed from xport to chdr system
|
||||
//
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Unidirectional AXI4-Stream interface
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Minimal - Interface Capable of continuous assignment
|
||||
interface AxiStreamIf #(
|
||||
int DATA_WIDTH = 64,
|
||||
|
||||
int USER_WIDTH = 1,
|
||||
int MAX_PACKET_BYTES = 0,
|
||||
bit TDATA = 1,
|
||||
bit TUSER = 1,
|
||||
bit TKEEP = 1,
|
||||
bit TLAST = 1
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst = 1'b0
|
||||
);
|
||||
|
||||
// We don't want to check this, but this is an example of how to
|
||||
// check an input parameter
|
||||
// initial begin
|
||||
// assert (DATA_WIDTH % 8 == 0) else begin
|
||||
// $display("DATA_WIDTH == %1d",DATA_WIDTH);
|
||||
// $fatal(1,"Invalid data width on AxiStreamIf");
|
||||
// end
|
||||
// end
|
||||
|
||||
localparam BYTES_PER_WORD = DATA_WIDTH/8;
|
||||
localparam DWIDTH = TDATA ? DATA_WIDTH : 0;
|
||||
localparam UWIDTH = TUSER ? USER_WIDTH : 0;
|
||||
localparam KWIDTH = TKEEP ? DATA_WIDTH/8 : 0;
|
||||
localparam LWIDTH = TLAST ? 1 : 0;
|
||||
localparam PACKED_WIDTH = DWIDTH + UWIDTH + KWIDTH + LWIDTH ;
|
||||
|
||||
// local type defs
|
||||
typedef logic [DATA_WIDTH-1:0] data_t;
|
||||
typedef logic [USER_WIDTH-1:0] user_t;
|
||||
typedef logic [DATA_WIDTH/8-1:0] keep_t;
|
||||
|
||||
// Signals that make up a unidirectional AXI-Stream interface
|
||||
logic tlast;
|
||||
logic tvalid;
|
||||
logic tready;
|
||||
data_t tdata;
|
||||
user_t tuser;
|
||||
keep_t tkeep;
|
||||
|
||||
//---------------------------------------
|
||||
// Trailing Bytes/Keep functions
|
||||
// Trailing byte of 0 means full word else trailing bytes is the
|
||||
// number of bytes in the last word.
|
||||
//---------------------------------------
|
||||
// bits needed to represent trailing bytes
|
||||
localparam TRAILING_WIDTH = $clog2(DATA_WIDTH/8);
|
||||
typedef logic [TRAILING_WIDTH-1:0] trailing_bytes_t;
|
||||
|
||||
// translate between bytes and tkeep
|
||||
function automatic trailing_bytes_t keep2trailing(keep_t keep);
|
||||
trailing_bytes_t bytes = '0;
|
||||
if (tlast == 1) begin
|
||||
// mux between values based on the high bit = 1
|
||||
for(int b = 0; b < DATA_WIDTH/8 ; b++) begin
|
||||
if (keep[b]) bytes = b+1;
|
||||
end
|
||||
end
|
||||
return bytes;
|
||||
endfunction : keep2trailing
|
||||
|
||||
function automatic keep_t trailing2keep(trailing_bytes_t bytes);
|
||||
keep_t keep = '1;
|
||||
if (tlast == 1 && bytes != 0) begin
|
||||
foreach(keep[b]) begin
|
||||
keep[b] = bytes > b;
|
||||
end
|
||||
end
|
||||
return keep;
|
||||
endfunction : trailing2keep
|
||||
|
||||
// View from the master side
|
||||
modport master (
|
||||
input clk, rst,
|
||||
output tvalid, tdata, tuser, tkeep, tlast,
|
||||
input tready,
|
||||
import keep2trailing,
|
||||
import trailing2keep
|
||||
);
|
||||
|
||||
// View from the slave side
|
||||
modport slave (
|
||||
input clk, rst,
|
||||
input tvalid, tdata, tuser, tkeep, tlast,
|
||||
output tready,
|
||||
import keep2trailing,
|
||||
import trailing2keep
|
||||
);
|
||||
|
||||
|
||||
endinterface : AxiStreamIf
|
||||
|
||||
// Full featured for packet modification. Must use procedural assignment.
|
||||
interface AxiStreamPacketIf #(
|
||||
int DATA_WIDTH = 64,
|
||||
int USER_WIDTH = 1,
|
||||
int MAX_PACKET_BYTES = 0,
|
||||
bit TDATA = 1,
|
||||
bit TUSER = 1,
|
||||
bit TKEEP = 1,
|
||||
bit TLAST = 1
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst = 1'b0
|
||||
);
|
||||
|
||||
// We don't want to check this, but this is an example of how to
|
||||
// check an input parameter:
|
||||
// initial begin
|
||||
// assert (DATA_WIDTH % 8 == 0) else begin
|
||||
// $display("DATA_WIDTH == %1d",DATA_WIDTH);
|
||||
// $fatal(1,"Invalid data width on AxiStreamIf");
|
||||
// end
|
||||
// end
|
||||
|
||||
localparam BYTES_PER_WORD = DATA_WIDTH/8;
|
||||
localparam MAX_PACKET_WORDS = MAX_PACKET_BYTES/BYTES_PER_WORD;
|
||||
// local type defs
|
||||
typedef logic [DATA_WIDTH-1:0] data_t;
|
||||
typedef logic [USER_WIDTH-1:0] user_t;
|
||||
typedef logic [DATA_WIDTH/8-1:0] keep_t;
|
||||
typedef logic [$clog2(MAX_PACKET_WORDS)-1:0] word_count_t;
|
||||
|
||||
// Signals that make up a unidirectional AXI-Stream interface
|
||||
logic tlast;
|
||||
logic tvalid;
|
||||
logic tready;
|
||||
data_t tdata;
|
||||
user_t tuser;
|
||||
keep_t tkeep;
|
||||
word_count_t word_count = 0;
|
||||
|
||||
if (MAX_PACKET_BYTES>0) begin
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
word_count <= 0;
|
||||
end else begin
|
||||
// reset at last
|
||||
if (tlast && tvalid && tready) begin
|
||||
word_count <= 0;
|
||||
// increment when valid and ready
|
||||
end else if (tvalid && tready)begin
|
||||
word_count <= word_count+1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------
|
||||
// Packing functions
|
||||
//---------------------------------------
|
||||
|
||||
localparam DWIDTH = TDATA ? DATA_WIDTH : 0;
|
||||
localparam UWIDTH = TUSER ? USER_WIDTH : 0;
|
||||
localparam KWIDTH = TKEEP ? DATA_WIDTH/8 : 0;
|
||||
localparam LWIDTH = TLAST ? 1 : 0;
|
||||
localparam PACKED_WIDTH = DWIDTH + UWIDTH + KWIDTH + LWIDTH ;
|
||||
typedef logic [PACKED_WIDTH-1:0] packed_t;
|
||||
|
||||
function automatic packed_t pack(INC_DATA=1,INC_USER=1,INC_KEEP=1,INC_LAST=1);
|
||||
logic [PACKED_WIDTH-1:0] data = 'X;
|
||||
|
||||
int USTART;
|
||||
int KSTART;
|
||||
int LSTART;
|
||||
|
||||
USTART = INC_DATA ? DWIDTH :0;
|
||||
KSTART = INC_USER ? USTART+UWIDTH :USTART;
|
||||
LSTART = INC_KEEP ? KSTART+KWIDTH :KSTART;
|
||||
|
||||
if (TDATA && INC_DATA) begin
|
||||
// in the LSB
|
||||
data[0+:DATA_WIDTH] = tdata;
|
||||
end
|
||||
if (TUSER && INC_USER) begin
|
||||
// in the 1st MIDDLE
|
||||
data[USTART+:USER_WIDTH] = tuser;
|
||||
end
|
||||
if (TKEEP && INC_KEEP) begin
|
||||
// in the 2nd MIDDLE
|
||||
data[KSTART+:DATA_WIDTH/8] = tkeep;
|
||||
end
|
||||
if (TLAST && INC_LAST) begin
|
||||
// in the MSB
|
||||
data[LSTART] = tlast;
|
||||
end
|
||||
return data;
|
||||
endfunction : pack
|
||||
|
||||
task automatic unpack (packed_t data,INC_DATA=1,INC_USER=1,INC_KEEP=1,INC_LAST=1);
|
||||
|
||||
int USTART;
|
||||
int KSTART;
|
||||
int LSTART;
|
||||
|
||||
USTART = INC_DATA ? DWIDTH :0;
|
||||
KSTART = INC_USER ? USTART+UWIDTH :USTART;
|
||||
LSTART = INC_KEEP ? KSTART+KWIDTH :KSTART;
|
||||
|
||||
if (TDATA && INC_DATA) begin
|
||||
// in the LSB
|
||||
tdata = data[0+:DATA_WIDTH];
|
||||
end
|
||||
if (TUSER && INC_USER) begin
|
||||
// in the 1st MIDDLE
|
||||
tuser = data[USTART+:USER_WIDTH];
|
||||
end
|
||||
if (TKEEP && INC_KEEP) begin
|
||||
// in the 2nd MIDDLE
|
||||
tkeep = data[KSTART+:DATA_WIDTH/8];
|
||||
end
|
||||
if (TLAST && INC_LAST) begin
|
||||
// in the MSB
|
||||
tlast = data[LSTART];
|
||||
end
|
||||
endtask : unpack
|
||||
|
||||
//---------------------------------------
|
||||
// Trailing Bytes/Keep functions
|
||||
// Trailing byte of 0 means full word else trailing bytes is the
|
||||
// number of bytes in the last word.
|
||||
//---------------------------------------
|
||||
// bits needed to represent trailing bytes
|
||||
localparam TRAILING_WIDTH = $clog2(DATA_WIDTH/8);
|
||||
typedef logic [TRAILING_WIDTH-1:0] trailing_bytes_t;
|
||||
|
||||
// translate between bytes and tkeep
|
||||
function automatic trailing_bytes_t keep2trailing(keep_t keep);
|
||||
trailing_bytes_t bytes = '0;
|
||||
if (tlast == 1) begin
|
||||
// mux between values based on the high bit = 1
|
||||
for(int b = 0; b < DATA_WIDTH/8 ; b++) begin
|
||||
if (keep[b]) bytes = b+1;
|
||||
end
|
||||
end
|
||||
return bytes;
|
||||
endfunction : keep2trailing
|
||||
|
||||
function automatic keep_t trailing2keep(trailing_bytes_t bytes);
|
||||
keep_t keep = '1;
|
||||
if (tlast == 1 && bytes != 0) begin
|
||||
foreach(keep[b]) begin
|
||||
keep[b] = bytes > b;
|
||||
end
|
||||
end
|
||||
return keep;
|
||||
endfunction : trailing2keep
|
||||
|
||||
// do the translation directly to/from the ifc
|
||||
function automatic keep_t get_trailing_bytes();
|
||||
localparam USER_TRAILING_WIDTH =
|
||||
USER_WIDTH >= TRAILING_WIDTH ? TRAILING_WIDTH : USER_WIDTH;
|
||||
assert (TUSER) else
|
||||
$fatal("Can't get trailing if TUSER doesn't exist");
|
||||
assert (USER_WIDTH >= TRAILING_WIDTH) else
|
||||
$fatal("USER_WIDTH is to narrow to contain trailing");
|
||||
return trailing2keep(tuser[USER_TRAILING_WIDTH-1:0]);
|
||||
endfunction : get_trailing_bytes
|
||||
|
||||
task automatic set_trailing_bytes(keep_t keep);
|
||||
localparam USER_TRAILING_WIDTH =
|
||||
USER_WIDTH >= TRAILING_WIDTH ? TRAILING_WIDTH : USER_WIDTH;
|
||||
assert (TUSER) else
|
||||
$fatal("Can't set trailing if TUSER doesn't exist");
|
||||
assert (USER_WIDTH >= TRAILING_WIDTH) else
|
||||
$fatal("USER_WIDTH is to narrow to set trailing");
|
||||
tuser[USER_TRAILING_WIDTH-1:0] = keep2trailing(keep);
|
||||
endtask : set_trailing_bytes
|
||||
|
||||
|
||||
//---------------------------------------
|
||||
// Packet PROGRESS functions
|
||||
//---------------------------------------
|
||||
// Notify when a byte is reached(VALID)
|
||||
function automatic bit reached_packet_byte(
|
||||
input int OFFSET
|
||||
);
|
||||
// constant because they only depend on offset
|
||||
int WORD_OFFSET;
|
||||
assert (MAX_PACKET_BYTES > 0) else
|
||||
$fatal(1,"checking packet on a non packet bus");
|
||||
// Constant
|
||||
WORD_OFFSET = OFFSET / (DATA_WIDTH/8);
|
||||
|
||||
return (word_count == WORD_OFFSET);
|
||||
|
||||
endfunction : reached_packet_byte
|
||||
|
||||
// Notify when a byte is being transmitted(VALID && READY)
|
||||
function automatic bit xfering_packet_byte(
|
||||
input int OFFSET
|
||||
);
|
||||
|
||||
return reached_packet_byte(OFFSET) && tvalid && tready;
|
||||
|
||||
endfunction : xfering_packet_byte
|
||||
|
||||
// drive functions (These are not particularly useful
|
||||
// but they guarantee the modules using the package don't
|
||||
// drive the interface with a continuous assignment
|
||||
task automatic drive_tlast(input logic last);
|
||||
tlast = last;
|
||||
endtask
|
||||
task automatic drive_tvalid(input logic valid);
|
||||
tvalid = valid;
|
||||
endtask
|
||||
task automatic drive_tready(input logic ready);
|
||||
tready = ready;
|
||||
endtask
|
||||
task automatic drive_tdata(input logic data);
|
||||
tdata = data;
|
||||
endtask
|
||||
task automatic drive_tuser(input logic user);
|
||||
tuser = user;
|
||||
endtask
|
||||
task automatic drive_tkeep(input logic keep);
|
||||
tkeep = keep;
|
||||
endtask
|
||||
function automatic word_count_t get_word_count();
|
||||
return word_count;
|
||||
endfunction
|
||||
|
||||
//---------------------------------------
|
||||
// Packet FIELD READ functions
|
||||
//
|
||||
// USAGE:
|
||||
//
|
||||
// // get the fields - don't use assign. assign will not activate with changes to in1.
|
||||
// always_comb begin : get_fields
|
||||
// eth_dst_addr_new = in1.get_packet_field48(eth_dst_addr_old,DST_MAC_BYTE,.NETWORK_ORDER(1));
|
||||
// reached_end_of_udp = in1.reached_packet_byte(DST_PORT_BYTE+3);// we have enough to decide
|
||||
// end
|
||||
//
|
||||
// // use the fields
|
||||
// always_comb begin : use_fields
|
||||
// if (reached_end_of_udp) begin // Wait until you know the field is fully captured before using it!
|
||||
// ** DO SOMETHING INTERESTING WITH est_dst_addr_new
|
||||
// end
|
||||
|
||||
|
||||
//---------------------------------------
|
||||
// Grab a byte from a passing stream
|
||||
function automatic logic [7:0] get_packet_byte(
|
||||
input logic [7:0] old_value,
|
||||
input int OFFSET
|
||||
);
|
||||
// constant because they only depend on offset
|
||||
int BYTE_OFFSET;
|
||||
|
||||
logic [7:0] new_value;
|
||||
|
||||
// Constant
|
||||
BYTE_OFFSET = OFFSET % (DATA_WIDTH/8);
|
||||
|
||||
// default : Stay the same
|
||||
new_value = old_value;
|
||||
|
||||
if (reached_packet_byte(OFFSET)) begin
|
||||
new_value = tdata[BYTE_OFFSET*8+:8];
|
||||
end
|
||||
return new_value;
|
||||
endfunction : get_packet_byte
|
||||
|
||||
// Grab a 16 bit field from a passing stream
|
||||
function automatic logic [15:0] get_packet_field16(
|
||||
input logic [15:0] old_value,
|
||||
input int OFFSET,
|
||||
input int NETWORK_ORDER=0
|
||||
);
|
||||
logic [15:0] new_value;
|
||||
|
||||
localparam BYTES=$size(new_value)/8;
|
||||
for (int i=0;i < BYTES; i++) begin
|
||||
if (NETWORK_ORDER==1) begin
|
||||
new_value[i*8+:8] = get_packet_byte(old_value[i*8+:8],OFFSET+BYTES-1-i);
|
||||
end else begin
|
||||
new_value[i*8+:8] = get_packet_byte(old_value[i*8+:8],OFFSET+i);
|
||||
end
|
||||
end
|
||||
return new_value;
|
||||
|
||||
endfunction : get_packet_field16
|
||||
|
||||
// Grab a 32 bit field from a passing stream
|
||||
function automatic logic [31:0] get_packet_field32(
|
||||
input logic [31:0] old_value,
|
||||
input int OFFSET,
|
||||
input int NETWORK_ORDER=0
|
||||
);
|
||||
logic [31:0] new_value;
|
||||
|
||||
localparam BYTES=$size(new_value)/8;
|
||||
for (int i=0;i < BYTES; i++) begin
|
||||
if (NETWORK_ORDER==1) begin
|
||||
new_value[i*8+:8] = get_packet_byte(old_value[i*8+:8],OFFSET+BYTES-1-i);
|
||||
end else begin
|
||||
new_value[i*8+:8] = get_packet_byte(old_value[i*8+:8],OFFSET+i);
|
||||
end
|
||||
end
|
||||
|
||||
return new_value;
|
||||
|
||||
endfunction : get_packet_field32
|
||||
|
||||
// Grab a 48 bit field from a passing stream
|
||||
function automatic logic [47:0] get_packet_field48(
|
||||
input logic [47:0] old_value,
|
||||
input int OFFSET,
|
||||
input int NETWORK_ORDER=0
|
||||
);
|
||||
logic [47:0] new_value;
|
||||
|
||||
localparam BYTES=$size(new_value)/8;
|
||||
for (int i=0;i < BYTES; i++) begin
|
||||
if (NETWORK_ORDER==1) begin
|
||||
new_value[i*8+:8] = get_packet_byte(old_value[i*8+:8],OFFSET+BYTES-1-i);
|
||||
end else begin
|
||||
new_value[i*8+:8] = get_packet_byte(old_value[i*8+:8],OFFSET+i);
|
||||
end
|
||||
end
|
||||
|
||||
return new_value;
|
||||
|
||||
endfunction : get_packet_field48
|
||||
|
||||
//---------------------------------------
|
||||
// Packet FIELD OVERWRITE functions
|
||||
//
|
||||
// USAGE:
|
||||
//
|
||||
// // Each call muxes data as it goes by. This chains together muxing which synthesis will simplify
|
||||
// always_comb begin : set_header_fields
|
||||
// v2e5.tdata = v2e4.tdata;
|
||||
// v2e5.put_packet_field48(mac_dst,DST_MAC_BYTE,.NETWORK_ORDER(1));
|
||||
// end
|
||||
//---------------------------------------
|
||||
|
||||
// Overwrite a byte in a passing stream
|
||||
task automatic put_packet_byte(
|
||||
input logic [7:0] new_value,
|
||||
input int OFFSET
|
||||
);
|
||||
// constant because they only depend on offset
|
||||
int BYTE_OFFSET;
|
||||
|
||||
// Constant
|
||||
BYTE_OFFSET = OFFSET % (DATA_WIDTH/8);
|
||||
if (reached_packet_byte(OFFSET)) begin
|
||||
tdata[BYTE_OFFSET*8+:8] = new_value;
|
||||
end
|
||||
endtask : put_packet_byte
|
||||
|
||||
// Overwrite a 16 bit field in a passing stream
|
||||
task automatic put_packet_field16(
|
||||
input logic [15:0] new_value,
|
||||
input int OFFSET,
|
||||
input int NETWORK_ORDER=0
|
||||
);
|
||||
localparam BYTES=$size(new_value)/8;
|
||||
for (int i=0;i < BYTES; i++) begin
|
||||
if (NETWORK_ORDER==1) begin
|
||||
put_packet_byte(new_value[i*8+:8],OFFSET+BYTES-1-i);
|
||||
end else begin
|
||||
put_packet_byte(new_value[i*8+:8],OFFSET+i);
|
||||
end
|
||||
end
|
||||
endtask : put_packet_field16
|
||||
|
||||
// Overwrite a 32 bit field in a passing stream
|
||||
task automatic put_packet_field32(
|
||||
input logic [31:0] new_value,
|
||||
input int OFFSET,
|
||||
input int NETWORK_ORDER=0
|
||||
);
|
||||
localparam BYTES=$size(new_value)/8;
|
||||
for (int i=0;i < BYTES; i++) begin
|
||||
if (NETWORK_ORDER==1) begin
|
||||
put_packet_byte(new_value[i*8+:8],OFFSET+BYTES-1-i);
|
||||
end else begin
|
||||
put_packet_byte(new_value[i*8+:8],OFFSET+i);
|
||||
end
|
||||
end
|
||||
endtask : put_packet_field32
|
||||
|
||||
// Overwrite a 48 bit field in a passing stream
|
||||
task automatic put_packet_field48(
|
||||
input logic [47:0] new_value,
|
||||
input int OFFSET,
|
||||
input int NETWORK_ORDER=0
|
||||
);
|
||||
localparam BYTES=$size(new_value)/8;
|
||||
for (int i=0;i < BYTES; i++) begin
|
||||
if (NETWORK_ORDER==1) begin
|
||||
put_packet_byte(new_value[i*8+:8],OFFSET+BYTES-1-i);
|
||||
end else begin
|
||||
put_packet_byte(new_value[i*8+:8],OFFSET+i);
|
||||
end
|
||||
end
|
||||
endtask : put_packet_field48
|
||||
|
||||
|
||||
// View from the master side
|
||||
modport master (
|
||||
input clk, rst,
|
||||
output tvalid, tdata, tuser, tkeep, tlast,
|
||||
input tready,
|
||||
//import methods
|
||||
import pack,
|
||||
import unpack,
|
||||
import keep2trailing,
|
||||
import trailing2keep,
|
||||
import get_trailing_bytes,
|
||||
import set_trailing_bytes,
|
||||
import get_word_count,
|
||||
import reached_packet_byte,
|
||||
import xfering_packet_byte,
|
||||
import get_packet_byte,
|
||||
import get_packet_field16,
|
||||
import get_packet_field32,
|
||||
import get_packet_field48,
|
||||
import put_packet_byte,
|
||||
import put_packet_field16,
|
||||
import put_packet_field32,
|
||||
import put_packet_field48
|
||||
);
|
||||
|
||||
// View from the slave side
|
||||
modport slave (
|
||||
input clk, rst,
|
||||
input tvalid, tdata, tuser, tkeep, tlast,
|
||||
output tready,
|
||||
//import methods
|
||||
import pack,
|
||||
import unpack,
|
||||
import keep2trailing,
|
||||
import trailing2keep,
|
||||
import get_trailing_bytes,
|
||||
import set_trailing_bytes,
|
||||
import get_word_count,
|
||||
import reached_packet_byte,
|
||||
import xfering_packet_byte,
|
||||
import get_packet_byte,
|
||||
import get_packet_field16,
|
||||
import get_packet_field32,
|
||||
import get_packet_field48,
|
||||
import put_packet_byte,
|
||||
import put_packet_field16,
|
||||
import put_packet_field32,
|
||||
import put_packet_field48
|
||||
);
|
||||
|
||||
|
||||
endinterface : AxiStreamPacketIf
|
||||
Reference in New Issue
Block a user