Files
b210-k7-fpga/lib/axi4s_sv/axi4s_packet_gate.sv
T
Andrew Moch 23be04661f 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
2020-06-25 14:44:04 -05:00

99 lines
2.9 KiB
Systemverilog

//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: axi4s_packet_gate
//
// Description:
// System Verilog wrapper for axi_gate_packet that accepts
// a AxiStreamIfc with slave_user/master_uer interface.
//
// Parameters:
// TDATA - store tData if 1
// TUSER - store tUser if 1
// SIZE - 2**SIZE words are stored
// USE_AS_BUFF - Allow the packet gate to be used as a buffer (uses more RAM)
// MIN_PKT_SIZE - log2 of minimum valid packet size (rounded down, used to
// reduce addr fifo size)
module axi4s_packet_gate #(
bit TDATA = 1,
bit TUSER = 1,
int SIZE = 10,
bit USE_AS_BUFF = 1,
int MIN_PKT_SIZE= 1
) (
input logic clear=1'b0,
input logic error=1'b0,
interface i, // AxiStreamIf or AxiStreamPacketIf
interface o // AxiStreamIf or AxiStreamPacketIf
);
`include "axi4s.vh"
// Parameter Checks
initial begin
assert (i.DATA_WIDTH == o.DATA_WIDTH) else
$fatal("DATA_WIDTH mismatch");
assert (i.USER_WIDTH == o.USER_WIDTH) else
$fatal("USER_WIDTH mismatch");
assert (i.TDATA == o.TDATA) else
$fatal("TDATA present mismatch");
assert (i.TUSER == o.TUSER) else
$fatal("TUSER present mismatch");
assert (i.TKEEP == o.TKEEP) else
$fatal("TKEEP present mismatch");
assert (i.TLAST == 1) else
$fatal("i.TLAST not present");
assert (o.TLAST == 1) else
$fatal("o.TLAST not present");
end
localparam WIDTH = i.DWIDTH + i.UWIDTH + i.KWIDTH;
AxiStreamPacketIf #(.DATA_WIDTH(i.DATA_WIDTH),.USER_WIDTH(i.USER_WIDTH),
.TDATA(i.TDATA),.TKEEP(i.TKEEP),.TUSER(i.TUSER),.TLAST(i.TLAST),
.MAX_PACKET_BYTES(i.MAX_PACKET_BYTES))
s0(i.clk,i.rst);
AxiStreamPacketIf #(.DATA_WIDTH(i.DATA_WIDTH),.USER_WIDTH(i.USER_WIDTH),
.TDATA(i.TDATA),.TKEEP(i.TKEEP),.TUSER(i.TUSER),.TLAST(i.TLAST),
.MAX_PACKET_BYTES(i.MAX_PACKET_BYTES))
s1(i.clk,i.rst);
// move from AxiStreamIfc to AxiStreamPacketIf
always_comb begin
`AXI4S_ASSIGN(s0,i)
end
// move from AxiStreamPacketIf to AxiStreamIfc
always_comb begin
`AXI4S_ASSIGN(o,s1)
end
logic [WIDTH-1:0] s0_data;
logic [WIDTH-1:0] s1_data;
always_comb s0_data = s0.pack(.INC_LAST(0));
always_comb s1.unpack(s1_data,.INC_LAST(0));
logic s0_ready, s1_valid, s1_last;
always_comb s0.tready = s0_ready;
always_comb s1.tvalid = s1_valid;
always_comb s1.tlast = s1_last;
axi_packet_gate #(
.WIDTH(WIDTH),.SIZE(SIZE), .USE_AS_BUFF(USE_AS_BUFF), .MIN_PKT_SIZE(MIN_PKT_SIZE)
) axi_packet_gate_i (
.clk(s0.clk), .reset(s0.rst), .clear(clear),
.i_terror(error),
.i_tdata(s0_data),
.i_tvalid(s0.tvalid),
.i_tready(s0_ready),
.i_tlast(s0.tlast),
.o_tdata(s1_data),
.o_tvalid(s1_valid),
.o_tready(s1.tready),
.o_tlast(s1_last)
);
endmodule : axi4s_packet_gate