File: axis_sideband_tuser.v

package info (click to toggle)
uhd 4.8.0.0%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 183,172 kB
  • sloc: cpp: 279,415; python: 109,850; ansic: 103,348; vhdl: 57,230; tcl: 20,007; xml: 8,581; makefile: 2,863; sh: 2,797; pascal: 230; javascript: 120; csh: 94; asm: 20; perl: 11
file content (124 lines) | stat: -rw-r--r-- 4,343 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// Copyright 2023 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: axis_sideband_tuser
//
// Description:
//
//   AXI stream buses often lack a pass-through tuser signal.
//   This block uses a FIFO to implement that functionality.
//   The FIFO can store a tuser entry for every bus transaction or
//   it can operate in packet mode where the tuser signal is assumed
//   to be constant during an entire packet to save resources.
//
//   NOTE: For buses / modules that consume a vector of samples (i.e. FFT block),
//         the FIFO size must be deep enough for the entire vector or a deadlock
//         can occur.
//
// Parameters:
//
//   WIDTH                : Width to tuser signal
//   FIFO_SIZE_LOG2       : Log2 size of FIFO
//   PACKET_MODE          : 0: Store tuser on every bus transaction
//                          1: Replicate tuser from first word in a packet
//                          2: Replicate tuser from last word in a packet, useful when tuser is EOB
//

`default_nettype none

module axis_sideband_tuser
#(
  parameter WIDTH                 = 32,
  parameter USER_WIDTH            = 1,
  parameter FIFO_SIZE_LOG2        = 5,
  parameter PACKET_MODE           = 1
)(
  // Clock/Reset
  input  wire                  clk,
  input  wire                  reset,

  // Toplevel AXI stream buses with tuser
  input  wire [WIDTH-1:0]      s_axis_tdata,
  input  wire [USER_WIDTH-1:0] s_axis_tuser,
  input  wire                  s_axis_tlast,
  input  wire                  s_axis_tvalid,
  output wire                  s_axis_tready,
  output wire [WIDTH-1:0]      m_axis_tdata,
  output wire [USER_WIDTH-1:0] m_axis_tuser,
  output wire                  m_axis_tlast,
  output wire                  m_axis_tvalid,
  input  wire                  m_axis_tready,

  // AXI stream buses to module / bus without tuser
  output wire [WIDTH-1:0]      m_axis_mod_tdata,
  output wire                  m_axis_mod_tlast,
  output wire                  m_axis_mod_tvalid,
  input  wire                  m_axis_mod_tready,
  input  wire [WIDTH-1:0]      s_axis_mod_tdata,
  input  wire                  s_axis_mod_tlast,
  input  wire                  s_axis_mod_tvalid,
  output wire                  s_axis_mod_tready
);

  wire [USER_WIDTH-1:0] fifo_in_tdata;
  wire                  fifo_in_tvalid;
  wire                  fifo_in_tready;
  wire [USER_WIDTH-1:0] fifo_out_tdata;
  wire                  fifo_out_tvalid;
  wire                  fifo_out_tready;

  axi_fifo #(
    .WIDTH    (USER_WIDTH),
    .SIZE     (FIFO_SIZE_LOG2))
  axi_fifo_tuser (
    .clk      (clk),
    .reset    (reset),
    .clear    (1'b0),
    .i_tdata  (fifo_in_tdata),
    .i_tvalid (fifo_in_tvalid),
    .i_tready (fifo_in_tready),
    .o_tdata  (fifo_out_tdata),
    .o_tvalid (fifo_out_tvalid),
    .o_tready (fifo_out_tready),
    .space    (),
    .occupied ()
  );

  reg first_word = 1'b1;
  always @(posedge clk) begin
    if (s_axis_tvalid & s_axis_tready) begin
      first_word <= s_axis_tlast;
    end
    if (reset) begin
      first_word <= 1'b1;
    end
  end

  assign fifo_in_tdata      = s_axis_tuser;
  assign fifo_in_tvalid     = m_axis_mod_tready & s_axis_tvalid &
                              (PACKET_MODE == 0 ? 1'b1         :
                               PACKET_MODE == 1 ? first_word   :
                               PACKET_MODE == 2 ? s_axis_tlast :
                               /* else */         1'b1);
  assign fifo_out_tready    = m_axis_tready & s_axis_mod_tvalid &
                              (PACKET_MODE == 0 ? 1'b1             :
                               PACKET_MODE == 1 ? s_axis_mod_tlast :
                               PACKET_MODE == 2 ? s_axis_mod_tlast :
                               /* else */         1'b1);

  assign s_axis_tready     = fifo_in_tready & m_axis_mod_tready;
  assign m_axis_mod_tdata  = s_axis_tdata;
  assign m_axis_mod_tlast  = s_axis_tlast;
  assign m_axis_mod_tvalid = fifo_in_tready & s_axis_tvalid;

  assign s_axis_mod_tready = m_axis_tready & fifo_out_tvalid;
  assign m_axis_tdata      = s_axis_mod_tdata;
  assign m_axis_tuser      = fifo_out_tdata;
  assign m_axis_tlast      = s_axis_mod_tlast;
  assign m_axis_tvalid     = s_axis_mod_tvalid & fifo_out_tvalid;

endmodule

`default_nettype wire