File: chdr_xb_ingress_buff.v

package info (click to toggle)
uhd 3.13.1.0-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 207,120 kB
  • sloc: cpp: 167,245; ansic: 86,841; vhdl: 53,420; python: 40,839; xml: 13,167; tcl: 5,688; makefile: 2,167; sh: 1,719; pascal: 230; csh: 94; asm: 20; perl: 11
file content (127 lines) | stat: -rw-r--r-- 4,595 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
125
126
127
//
// Copyright 2018 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: chdr_ingress_buff
// Description:
//   Ingress buffer module that does the following:
//   - Stores and gates an incoming packet
//   - Looks up destination in routing table and attaches a tdest for the packet

module chdr_xb_ingress_buff #(
  parameter WIDTH       = 64,
  parameter SIZE        = 5,
  parameter XB_NPORTS   = 8,
  parameter SID_OFFSET  = 0,
  parameter SID_WIDTH   = 16
) (
  input  wire                         clk,
  input  wire                         reset,
  // CHDR input port
  input  wire [WIDTH-1:0]             s_axis_chdr_tdata,
  input  wire                         s_axis_chdr_tlast,
  input  wire                         s_axis_chdr_tvalid,
  output wire                         s_axis_chdr_tready,
  // CHDR output port (with a tdest and tkeep)
  output wire [WIDTH-1:0]             m_axis_chdr_tdata,
  output wire [$clog2(XB_NPORTS)-1:0] m_axis_chdr_tdest,
  output wire                         m_axis_chdr_tkeep,
  output wire                         m_axis_chdr_tlast,
  output wire                         m_axis_chdr_tvalid,
  input  wire                         m_axis_chdr_tready,
  // Find port going to routing table
  output wire [SID_WIDTH-1:0]         m_axis_find_tdata,
  output wire                         m_axis_find_tvalid,
  input  wire                         m_axis_find_tready,
  // Result port from routing table
  input  wire [$clog2(XB_NPORTS)-1:0] s_axis_result_tdata,
  input  wire                         s_axis_result_tkeep,
  input  wire                         s_axis_result_tvalid,
  output wire                         s_axis_result_tready
);
  //----------------------------------------------------
  // Payload packet state tracker
  //----------------------------------------------------

  localparam [0:0] ST_HEAD = 1'd0;
  localparam [0:0] ST_BODY = 1'd1;

  reg [0:0] in_state = ST_HEAD, out_state = ST_HEAD;
  always @(posedge clk) begin
    if (reset) begin
      in_state <= ST_HEAD;
    end else if (s_axis_chdr_tvalid & s_axis_chdr_tready) begin
      if (in_state == ST_HEAD) begin
        in_state <= ST_BODY;
      end else begin
        in_state <= s_axis_chdr_tlast ? ST_HEAD : ST_BODY;
      end
    end
  end

  always @(posedge clk) begin
    if (reset) begin
      out_state <= ST_HEAD;
    end else if (m_axis_chdr_tvalid & m_axis_chdr_tready) begin
      if (out_state == ST_HEAD) begin
        out_state <= ST_BODY;
      end else begin
        out_state <= m_axis_chdr_tlast ? ST_HEAD : ST_BODY;
      end
    end
  end

  //----------------------------------------------------
  // Packet buffer and destination FIFO
  //----------------------------------------------------

  wire pkt_gate_i_tready, pkt_gate_o_tvalid, find_fifo_i_tready;
  axi_packet_gate #(.WIDTH(WIDTH), .SIZE(SIZE)) pkt_gate_i (
    .clk      (clk), 
    .reset    (reset), 
    .clear    (1'b0),
    .i_tdata  (s_axis_chdr_tdata),
    .i_tlast  (s_axis_chdr_tlast),
    .i_tvalid (s_axis_chdr_tvalid & s_axis_chdr_tready),  //NOTE: Violates AXIS but OK since FIFO downstream
    .i_tready (pkt_gate_i_tready),
    .i_terror (1'b0),
    .o_tdata  (m_axis_chdr_tdata),
    .o_tlast  (m_axis_chdr_tlast),
    .o_tvalid (pkt_gate_o_tvalid),
    .o_tready (m_axis_chdr_tready)
  );

  axi_fifo #(.WIDTH(SID_WIDTH), .SIZE(1)) find_fifo_i (
    .clk      (clk), 
    .reset    (reset), 
    .clear    (1'b0),
    .i_tdata  (s_axis_chdr_tdata[SID_OFFSET+:SID_WIDTH]),
    .i_tvalid ((in_state == ST_HEAD) & s_axis_chdr_tvalid & s_axis_chdr_tready),  //NOTE: Violates AXIS but OK since FIFO downstream
    .i_tready (find_fifo_i_tready),
    .o_tdata  (m_axis_find_tdata),
    .o_tvalid (m_axis_find_tvalid),
    .o_tready (m_axis_find_tready),
    .space    (),
    .occupied ()
  );
  assign s_axis_chdr_tready = pkt_gate_i_tready & (in_state == ST_HEAD ? find_fifo_i_tready : 1'b1);

  wire dst_fifo_o_tvalid;
  axi_fifo #(.WIDTH($clog2(XB_NPORTS)+1), .SIZE(1)) res_fifo_i (
    .clk      (clk), 
    .reset    (reset), 
    .clear    (1'b0),
    .i_tdata  ({s_axis_result_tkeep, s_axis_result_tdata}),
    .i_tvalid (s_axis_result_tvalid),
    .i_tready (s_axis_result_tready),
    .o_tdata  ({m_axis_chdr_tkeep, m_axis_chdr_tdest}),
    .o_tvalid (dst_fifo_o_tvalid),
    .o_tready (m_axis_chdr_tready & m_axis_chdr_tvalid & (out_state == ST_HEAD)),
    .space    (),
    .occupied ()
  );
  assign m_axis_chdr_tvalid = pkt_gate_o_tvalid & (out_state == ST_HEAD ? dst_fifo_o_tvalid : 1'b1);

endmodule