aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/gpif2/gpif2_to_fifo64.v
blob: 7281275a313cac801d16d38e874bb1e47f57d6e3 (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
//
// Copyright 2012-2013 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


module gpif2_to_fifo64
  #(
    parameter FIFO_SIZE = 9,
    parameter MTU = 12
    )
    (
     //input interface
     input gpif_clk,
     input gpif_rst,
     input [31:0] i_tdata,
     input i_tlast,
     input i_tvalid,
     output i_tready,
     output fifo_has_space,
     output fifo_nearly_full,

     //output fifo interface
     input fifo_clk,
     input fifo_rst,
     output [63:0] o_tdata,
     output o_tlast,
     output o_tvalid,
     input o_tready,

     output bus_error,
     output [31:0] debug
     );

   wire [31:0] 	    int_tdata;
   wire 	    int_tlast;
   wire 	    int_tvalid, int_tready;

   wire [31:0] 	    int0_tdata;
   wire 	    int0_tlast, int0_tvalid, int0_tready;

   //
   // Generate flags that show if initial FIFO's can accept a maximum sized burst from the FX3
   // or if the FIFO is about to fill.
   //
   wire [15:0] 	    space;
   assign 	    fifo_has_space = space >= (1 << MTU);
   assign 	    fifo_nearly_full = (space < 6); // 5 spaces left.

   //
   // This FIFO is provdied purely to ease FPGA timing closure as data is coming from I/O pins.
   //
   axi_fifo #(.WIDTH(33), .SIZE(5)) ingress_timing_fifo
     (
      .clk(gpif_clk), .reset(gpif_rst), .clear(1'b0),
      .i_tdata({i_tlast, i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready), .space(),
      .o_tdata({int0_tlast, int0_tdata}), .o_tvalid(int0_tvalid), .o_tready(int0_tready), .occupied()
      );

   //
   // This FIFO provides space to accept a single burst from FX3 and it's fullness drives flags to GPIF2 logic
   //
   axi_fifo_legacy #(.WIDTH(33), .SIZE(MTU)) min_read_buff
     (
      .clk(gpif_clk), .reset(gpif_rst), .clear(1'b0),
      .i_tdata({int0_tlast, int0_tdata}), .i_tvalid(int0_tvalid), .i_tready(int0_tready), .space(space),
      .o_tdata({int_tlast, int_tdata}), .o_tvalid(int_tvalid), .o_tready(int_tready), .occupied()
      );

   //
   // This logic allows signals to cross from the GPIF2 clock domain to the BUS clock domain.
   // It may now be obselete if bus_clk and gpif_clk are merged
   //
   wire [31:0] 	    chk_tdata;
   wire 	    chk_tlast;
   wire 	    chk_tvalid, chk_tready;

   axi_fifo_2clk #(.WIDTH(33), .SIZE(FIFO_SIZE)) cross_clock_fifo
     (
      .reset(fifo_rst | gpif_rst),
      .i_aclk(gpif_clk), .i_tdata({int_tlast, int_tdata}), .i_tvalid(int_tvalid), .i_tready(int_tready),
      .o_aclk(fifo_clk), .o_tdata({chk_tlast, chk_tdata}), .o_tvalid(chk_tvalid), .o_tready(chk_tready)
      );

   //
   // Performs basic tests on incomming packets such as testing if size on the wire patches
   // the internal size field. Uses axi_packet_gate internally so can back pressure upstream if
   // packet needs to be dropped.
   //
   wire [31:0] 	    o32_tdata;
   wire 	    o32_tlast;
   wire 	    o32_tvalid, o32_tready;

   gpif2_error_checker #(.SIZE(MTU)) checker
     (
      .clk(fifo_clk), .reset(fifo_rst), .clear(1'b0),
      .i_tdata(chk_tdata), .i_tlast(chk_tlast), .i_tvalid(chk_tvalid), .i_tready(chk_tready),
      .o_tdata(o32_tdata), .o_tlast(o32_tlast), .o_tvalid(o32_tvalid), .o_tready(o32_tready),
      .bus_error(bus_error), .debug()
      );

   //assign o32_tdata = chk_tdata;
   //assign o32_tlast = chk_tlast;
   //assign o32_tvalid = chk_tvalid;
   //assign chk_tready = o32_tready;

   //
   // Convert 32bit AXIS bus to 64bit
   //
   axi_fifo32_to_fifo64 fifo32_to_fifo64
     (
      .clk(fifo_clk), .reset(fifo_rst), .clear(1'b0),
      .i_tdata(o32_tdata), .i_tuser(2'b0/*always 32 bits*/), .i_tlast(o32_tlast), .i_tvalid(o32_tvalid), .i_tready(o32_tready),
      .o_tdata(o_tdata), .o_tuser(/*ignored cuz vita has len*/), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready)
      );


   /////////////////////////////////////////////
   //
   // Debug logic only
   //
   /////////////////////////////////////////////

   reg 		    o_tready_debug;
   reg 		    o_tvalid_debug;
   reg 		    o_tlast_debug;
   reg 		    i_tready_debug;
   reg 		    i_tvalid_debug;
   reg 		    i_tlast_debug;

   always @(posedge gpif_clk) begin
   	    o_tready_debug <= o_tready;
 	    o_tvalid_debug <= o_tvalid;
 	    o_tlast_debug <= o_tlast;
  	    i_tready_debug <= i_tready;
  	    i_tvalid_debug <= i_tvalid;
	    i_tlast_debug <= i_tlast;
   end

   assign debug = {26'h0,
		   o_tready_debug,
    		   o_tvalid_debug,
    		   o_tlast_debug,
    		   i_tready_debug,
    		   i_tvalid_debug,
    		   i_tlast_debug
		   };


endmodule //fifo_to_gpif2