aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/packet_proc/eth_interface.v
blob: e6fa3252d3f42f798299e641e57768b49382e7b3 (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Adapts from internal VITA to ethernet packets.  Also handles ZPU and ethernet crossover interfaces.

module eth_interface
  #(parameter BASE=0,
    parameter XO_FIFOSIZE=10,
    parameter ZPU_FIFOSIZE=10,
    parameter VITA_FIFOSIZE=10,
    parameter ETHOUT_FIFOSIZE=10)
   (input clk, input reset, input clear,
    input set_stb, input [7:0] set_addr, input [31:0] set_data,
    // Eth ports
    output [63:0] eth_tx_tdata, output [3:0] eth_tx_tuser, output eth_tx_tlast, output eth_tx_tvalid, input eth_tx_tready,
    input [63:0] eth_rx_tdata, input [3:0] eth_rx_tuser, input eth_rx_tlast, input eth_rx_tvalid, output eth_rx_tready,
    // Vita router interface
    output [63:0] e2v_tdata, output e2v_tlast, output e2v_tvalid, input e2v_tready,
    input [63:0] v2e_tdata, input v2e_tlast, input v2e_tvalid, output v2e_tready,
    // Ethernet crossover
    output [63:0] xo_tdata, output [3:0] xo_tuser, output xo_tlast, output xo_tvalid, input xo_tready,
    input [63:0] xi_tdata, input [3:0] xi_tuser, input xi_tlast, input xi_tvalid, output xi_tready,
    // ZPU
    output [63:0] e2z_tdata, output [3:0] e2z_tuser, output e2z_tlast, output e2z_tvalid, input e2z_tready,
    input [63:0] z2e_tdata, input [3:0] z2e_tuser, input z2e_tlast, input z2e_tvalid, output z2e_tready,
    // Debug
    output [31:0] debug_flags,
    output [31:0] debug
    );

   wire [63:0] 	  v2ef_tdata;
   wire [3:0] 	  v2ef_tuser;
   wire 	  v2ef_tlast, v2ef_tvalid, v2ef_tready;

   // //////////////////////////////////////////////////////////////
   // Incoming Ethernet path
   //  Includes FIFO on the output going to ZPU

   wire [63:0] 	  epg_tdata_int;
   wire [3:0] 	  epg_tuser_int;
   wire 	  epg_tlast_int, epg_tvalid_int, epg_tready_int;
   
   //
   // Packet gate ensures on entire ingressing packet is buffered before feeding it downstream so that it bursts
   // efficiently internally without holding resources allocted for longer than optimal. This also means that an upstream
   // error discovered in the packet can allow the packet to be destroyed here, before it gets deeper into the USRP.
   //
   axi_packet_gate #(.WIDTH(68), .SIZE(10)) packet_gater //holds 8K pkts
     (.clk(clk), .reset(reset), .clear(clear),

      .i_tdata({eth_rx_tuser, eth_rx_tdata}), .i_tlast(eth_rx_tlast),
      .i_terror(eth_rx_tuser[3]), //top bit of user bus is error
      .i_tvalid(eth_rx_tvalid), .i_tready(eth_rx_tready),

      .o_tdata({epg_tuser_int, epg_tdata_int}), .o_tlast(epg_tlast_int),
      .o_tvalid(epg_tvalid_int), .o_tready(epg_tready_int));

   //
   // Based on programmed rules, parse network headers and decide which internal destination(s) this packet will be forwarded to.
   //
   wire [63:0] 	  e2z_tdata_int;
   wire [3:0] 	  e2z_tuser_int;
   wire 	  e2z_tlast_int, e2z_tvalid_int, e2z_tready_int;
   wire [2:0]	  dispatch_debug_flags;
   
   eth_dispatch #(.BASE(BASE+8)) eth_dispatch
     (.clk(clk), .reset(reset), .clear(clear),
      .set_stb(set_stb), .set_addr(set_addr) , .set_data(set_data),
      .in_tdata(epg_tdata_int), .in_tuser(epg_tuser_int), .in_tlast(epg_tlast_int), .in_tvalid(epg_tvalid_int), .in_tready(epg_tready_int),
      .vita_tdata(e2v_tdata), .vita_tlast(e2v_tlast), .vita_tvalid(e2v_tvalid), .vita_tready(e2v_tready),
      .zpu_tdata(e2z_tdata_int), .zpu_tuser(e2z_tuser_int), .zpu_tlast(e2z_tlast_int), .zpu_tvalid(e2z_tvalid_int), .zpu_tready(e2z_tready_int),
      .xo_tdata(xo_tdata), .xo_tuser(xo_tuser), .xo_tlast(xo_tlast), .xo_tvalid(xo_tvalid), .xo_tready(xo_tready), // to other eth port
      .debug_flags(dispatch_debug_flags),.debug(debug));

   //
   // ZPU can be slow to respond (relative to packet wirespeed) so extra buffer for packets destined there so it doesn't back up.
   //
   axi_fifo #(.WIDTH(69),.SIZE(ZPU_FIFOSIZE)) zpu_fifo
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata({e2z_tlast_int,e2z_tuser_int,e2z_tdata_int}), .i_tvalid(e2z_tvalid_int), .i_tready(e2z_tready_int),
      .o_tdata({e2z_tlast,e2z_tuser,e2z_tdata}), .o_tvalid(e2z_tvalid), .o_tready(e2z_tready));

   // //////////////////////////////////////////////////////////////
   // Outgoing Ethernet path
   //  Includes FIFOs on path from VITA router, from ethernet crossover, and on the overall output

   wire [63:0] 	  eth_tx_tdata_int;
   wire [3:0] 	  eth_tx_tuser_int;
   wire 	  eth_tx_tlast_int, eth_tx_tvalid_int, eth_tx_tready_int;

   wire [63:0] 	  xi_tdata_int;
   wire [3:0] 	  xi_tuser_int;
   wire 	  xi_tlast_int, xi_tvalid_int, xi_tready_int;

   wire [63:0] 	  v2e_tdata_int;
   wire 	  v2e_tlast_int, v2e_tvalid_int, v2e_tready_int;
   
   axi_fifo #(.WIDTH(65),.SIZE(VITA_FIFOSIZE)) vitaout_fifo
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata({v2e_tlast,v2e_tdata}), .i_tvalid(v2e_tvalid), .i_tready(v2e_tready),
      .o_tdata({v2e_tlast_int,v2e_tdata_int}), .o_tvalid(v2e_tvalid_int), .o_tready(v2e_tready_int));

   chdr_eth_framer #(.BASE(BASE)) my_eth_framer
     (.clk(clk), .reset(reset), .clear(clear),
      .set_stb(set_stb), .set_addr(set_addr) , .set_data(set_data),
      .in_tdata(v2e_tdata_int), .in_tlast(v2e_tlast_int), .in_tvalid(v2e_tvalid_int), .in_tready(v2e_tready_int),
      .out_tdata(v2ef_tdata), .out_tuser(v2ef_tuser), .out_tlast(v2ef_tlast), .out_tvalid(v2ef_tvalid), .out_tready(v2ef_tready),
      .debug());

   axi_fifo #(.WIDTH(69),.SIZE(XO_FIFOSIZE)) xo_fifo
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata({xi_tlast,xi_tuser,xi_tdata}), .i_tvalid(xi_tvalid), .i_tready(xi_tready),
      .o_tdata({xi_tlast_int,xi_tuser_int,xi_tdata_int}), .o_tvalid(xi_tvalid_int), .o_tready(xi_tready_int));

   axi_mux4 #(.PRIO(0), .WIDTH(68)) eth_mux
     (.clk(clk), .reset(reset), .clear(clear),
      .i0_tdata({z2e_tuser,z2e_tdata}), .i0_tlast(z2e_tlast), .i0_tvalid(z2e_tvalid), .i0_tready(z2e_tready),
      .i1_tdata({v2ef_tuser,v2ef_tdata}), .i1_tlast(v2ef_tlast), .i1_tvalid(v2ef_tvalid), .i1_tready(v2ef_tready),
      .i2_tdata({xi_tuser_int,xi_tdata_int}), .i2_tlast(xi_tlast_int), .i2_tvalid(xi_tvalid_int), .i2_tready(xi_tready_int),
      .i3_tdata(), .i3_tlast(), .i3_tvalid(1'b0), .i3_tready(),
      .o_tdata({eth_tx_tuser_int,eth_tx_tdata_int}), .o_tlast(eth_tx_tlast_int), .o_tvalid(eth_tx_tvalid_int), .o_tready(eth_tx_tready_int));

   axi_fifo #(.WIDTH(69),.SIZE(ETHOUT_FIFOSIZE)) ethout_fifo
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata({eth_tx_tlast_int,eth_tx_tuser_int,eth_tx_tdata_int}), .i_tvalid(eth_tx_tvalid_int), .i_tready(eth_tx_tready_int),
      .o_tdata({eth_tx_tlast,eth_tx_tuser,eth_tx_tdata}), .o_tvalid(eth_tx_tvalid), .o_tready(eth_tx_tready));


   //
   // Provide instrumentation so that abnormal FIFO conditions can be identifed.
   //
/* -----\/----- EXCLUDED -----\/-----

   setting_reg #(.my_addr(BASE+15), .awidth(16), .width(1)) sr_reset_fifo_debug
     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
      .in(set_data),.out(),.changed(clear_debug_flags));

   always @(posedge clk)
     if (reset)
       debug_flags <= 0;
     else if (clear_debug_flags)
       debug_flags <= 0;
     else
       debug_flags <= debug_flags | {eth_rx_tuser[3],
				     ~eth_tx_tready_int,
				     ~xi_tready,
				     ~v2e_tready,
				     ~e2z_tready_int,
				     ~eth_rx_tready,
				     ~dispatch_debug_flags[2:0]};
 -----/\----- EXCLUDED -----/\----- */
   
   assign debug_flags = {eth_rx_tuser[3],
				     ~eth_tx_tready_int,
				     ~xi_tready,
				     ~v2e_tready,
				     ~e2z_tready_int,
				     ~eth_rx_tready,
				     ~dispatch_debug_flags[2:0]};	  
     

endmodule // eth_interface