1//
2// Copyright 2013 Ettus Research LLC
3// Copyright 2017 Ettus Research, a National Instruments Company
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6//
7
8// Parameters:
9// - DMA_STREAM_WIDTH: Width of the data bus. It'll be a big suprise if this is
10//                     anything other than 64.
11// - NUM_TX_STREAMS: Number of TX FIFOs.
12// - NUM_RX_STREAMS: Number of RX FIFOs. Note: Despite having two different
13//                   parameters, NUM_TX_STREAMS and NUM_RX_STREAMS need to be
14//                   identical.
15
16`define GET_DMA_BUS(parallel_bus, chan_idx) parallel_bus[(DMA_STREAM_WIDTH*(chan_idx+1))-1:(DMA_STREAM_WIDTH*chan_idx)]
17`define GET_FSIZE_BUS(parallel_bus, chan_idx) parallel_bus[(DMA_FRAME_SIZE_WIDTH*(chan_idx+1))-1:(DMA_FRAME_SIZE_WIDTH*chan_idx)]
18`define GET_SWAP_BUS(parallel_bus, chan_idx) parallel_bus[(3*(chan_idx+1))-1:(3*chan_idx)]
19
20module x300_pcie_int #(
21    parameter DMA_STREAM_WIDTH     = 64,
22    parameter NUM_TX_STREAMS       = 6,
23    parameter NUM_RX_STREAMS       = 6,
24    parameter REGPORT_ADDR_WIDTH   = 20,
25    parameter REGPORT_DATA_WIDTH   = 32,
26    parameter IOP2_MSG_WIDTH       = 64,
27    parameter BUS_CLK_RATE         = 32'd166666666
28) (
29    //---------------------------------------------------------
30    // Clocks and Resets
31    //---------------------------------------------------------
32    input           ioport2_clk,
33    input           bus_clk,
34    input           bus_rst,
35
36    //---------------------------------------------------------
37    // DMA streams to/from Chinch Interface to IoPort2 (Domain: ioport2_clk)
38    //---------------------------------------------------------
39    input  [(NUM_TX_STREAMS*DMA_STREAM_WIDTH)-1:0]  dmatx_tdata_iop2,
40    input  [NUM_TX_STREAMS-1:0]                     dmatx_tvalid_iop2,
41    output [NUM_TX_STREAMS-1:0]                     dmatx_tready_iop2,
42
43    output [(NUM_RX_STREAMS*DMA_STREAM_WIDTH)-1:0]  dmarx_tdata_iop2,
44    output [NUM_RX_STREAMS-1:0]                     dmarx_tvalid_iop2,
45    input  [NUM_RX_STREAMS-1:0]                     dmarx_tready_iop2,
46
47    //---------------------------------------------------------
48    // DMA stream to/from crossbar (Domain: bus_clk)
49    //---------------------------------------------------------
50    output [DMA_STREAM_WIDTH-1:0]        dmatx_tdata,
51    output [2:0]                         dmatx_tuser,
52    output                               dmatx_tvalid,
53    output                               dmatx_tlast,
54    input                                dmatx_tready,
55
56    input  [DMA_STREAM_WIDTH-1:0]        dmarx_tdata,
57    input  [2:0]                         dmarx_tuser,
58    input                                dmarx_tvalid,
59    input                                dmarx_tlast,
60    output                               dmarx_tready,
61
62    //---------------------------------------------------------
63    // PCIe User register port (Domain: ioport2_clk)
64    //---------------------------------------------------------
65    input                           pcie_usr_reg_wr,
66    input                           pcie_usr_reg_rd,
67    input  [REGPORT_ADDR_WIDTH-1:0] pcie_usr_reg_addr,
68    input  [REGPORT_DATA_WIDTH-1:0] pcie_usr_reg_data_in,
69    input  [1:0]                    pcie_usr_reg_len,
70    output [REGPORT_DATA_WIDTH-1:0] pcie_usr_reg_data_out,
71    output                          pcie_usr_reg_rc,
72    output                          pcie_usr_reg_rdy,
73
74    //---------------------------------------------------------
75    // PCIe Chinch register port (Domain: ioport2_clk)
76    //---------------------------------------------------------
77    output                          chinch_reg_wr,
78    output                          chinch_reg_rd,
79    output [REGPORT_ADDR_WIDTH-1:0] chinch_reg_addr,
80    output [REGPORT_DATA_WIDTH-1:0] chinch_reg_data_out,
81    output [1:0]                    chinch_reg_len,
82    input  [REGPORT_DATA_WIDTH-1:0] chinch_reg_data_in,
83    input                           chinch_reg_rc,
84    input                           chinch_reg_rdy,
85
86    //---------------------------------------------------------
87    // Message FIFOs to/from the core logic (Domain: bus_clk)
88    //---------------------------------------------------------
89    input [IOP2_MSG_WIDTH-1:0]      rego_tdata,
90    input                           rego_tvalid,
91    input                           rego_tlast,
92    output                          rego_tready,
93
94    output [IOP2_MSG_WIDTH-1:0]     regi_tdata,
95    output                          regi_tvalid,
96    output                          regi_tlast,
97    input                           regi_tready,
98
99    //---------------------------------------------------------
100    // Misc
101    //---------------------------------------------------------
102    input [15:0]    misc_status,
103    output [127:0]  debug
104);
105
106    localparam REG_CLK_XING_FIFO_SIZE = 5;  //Will synthesize fifo_short_2clk
107    localparam DMA_CLK_XING_FIFO_SIZE = 5;  //Will synthesize fifo_short_2clk
108    localparam DMA_PKT_GATE_FIFO_SIZE = 11; //Room for 2 8k packets
109    localparam DMA_FRAME_SIZE_WIDTH   = 16;
110    localparam DMA_RX_DEST_WIDTH      = $clog2(NUM_RX_STREAMS);
111
112    //*******************************************************************************
113    // Message FIFO translator + clock crossing
114    //
115    wire        msgo_tvalid, msgi_tvalid, msgo_tready, msgi_tready;
116    wire [63:0] msgo_tdata, msgi_tdata;
117
118
119    wire        pcie_out_valid, pcie_in_valid;
120    wire [63:0] pcie_out_msg, pcie_in_msg;
121
122    //Link chinch register port and user register port to AXI message FIFOs
123    wire        iop2_rd_response, iop2_wr_request, iop2_rd_request;
124    wire [31:0] iop2_data;
125
126    wire        chinch_reg_is_half_word;
127    ioport2_msg_decode pcie_out_msg_decoder (
128        .message(pcie_out_msg),
129        .rd_response(iop2_rd_response), .wr_request(iop2_wr_request), .rd_request(iop2_rd_request), .half_word(chinch_reg_is_half_word),
130        .address(chinch_reg_addr), .data(iop2_data));
131    assign chinch_reg_len = chinch_reg_is_half_word ? 2'b01 : 2'b10;
132
133    assign pcie_usr_reg_rc          = iop2_rd_response & pcie_out_valid;
134    assign chinch_reg_wr            = iop2_wr_request & pcie_out_valid;
135    assign chinch_reg_rd            = iop2_rd_request & pcie_out_valid;
136    assign chinch_reg_data_out      = iop2_data;
137    assign pcie_usr_reg_data_out    = iop2_data;
138
139    ioport2_msg_encode pcie_in_msg_encoder (
140        .rd_response(chinch_reg_rc), .wr_request(pcie_usr_reg_wr), .rd_request(pcie_usr_reg_rd), .half_word(pcie_usr_reg_len == 2'b01),
141        .address(pcie_usr_reg_addr), .data(chinch_reg_rc ? chinch_reg_data_in : pcie_usr_reg_data_in),
142        .message(pcie_in_msg));
143
144    assign pcie_in_valid = chinch_reg_rc | pcie_usr_reg_wr | pcie_usr_reg_rd;
145
146    //Cross from the Ioport2 clock domain to the bus clock domain
147    axi_fifo_2clk #(.WIDTH(64), .SIZE(REG_CLK_XING_FIFO_SIZE)) pcie_out_msg_fifo (
148        .reset(bus_rst),
149        .i_aclk(bus_clk), .i_tdata(msgo_tdata), .i_tvalid(msgo_tvalid), .i_tready(msgo_tready),
150        .o_aclk(ioport2_clk), .o_tdata(pcie_out_msg), .o_tvalid(pcie_out_valid), .o_tready(chinch_reg_rdy | pcie_usr_reg_rc));
151
152    axi_fifo_2clk #(.WIDTH(64), .SIZE(REG_CLK_XING_FIFO_SIZE)) pcie_in_msg_fifo (
153        .reset(bus_rst),
154        .i_aclk(ioport2_clk), .i_tdata(pcie_in_msg), .i_tvalid(pcie_in_valid), .i_tready(pcie_usr_reg_rdy),
155        .o_aclk(bus_clk), .o_tdata(msgi_tdata), .o_tvalid(msgi_tvalid), .o_tready(msgi_tready));
156    //
157    //*******************************************************************************
158
159    wire [NUM_TX_STREAMS-1:0]                           dmatx_clear, dmatx_enabled;
160    wire [NUM_TX_STREAMS-1:0]                           dmatx_samp_stb, dmatx_pkt_stb, dmatx_busy, dmatx_error;
161    wire [(NUM_TX_STREAMS*DMA_FRAME_SIZE_WIDTH)-1:0]    dmatx_frame_size;
162
163    wire [NUM_RX_STREAMS-1:0]                           dmarx_clear, dmarx_enabled;
164    wire [NUM_RX_STREAMS-1:0]                           dmarx_samp_stb, dmarx_pkt_stb, dmarx_busy, dmarx_error;
165    wire [(NUM_RX_STREAMS*DMA_FRAME_SIZE_WIDTH)-1:0]    dmarx_frame_size;
166    wire [DMA_STREAM_WIDTH-1:0]                         dmarx_header;
167
168    //*******************************************************************************
169    // PCIe message/register endpoints
170    //
171    wire [63:0] basic_regi_tdata,  dmatx_regi_tdata,  dmarx_regi_tdata;
172    wire        basic_regi_tvalid, dmatx_regi_tvalid, dmarx_regi_tvalid;
173    wire        basic_regi_tready, dmatx_regi_tready, dmarx_regi_tready;
174    wire [63:0] basic_rego_tdata,  dmatx_rego_tdata,  dmarx_rego_tdata;
175    wire        basic_rego_tvalid, dmatx_rego_tvalid, dmarx_rego_tvalid;
176    wire        basic_rego_tready, dmatx_rego_tready, dmarx_rego_tready;
177
178    pcie_iop2_msg_arbiter #(
179        //(DO NOT USE)                                //0x00000 - 0x3FFFC: Reserved LVFPGA Core Space
180        .E0_ADDR(20'h40000), .E0_MASK(20'hFFE00),     //0x40000 - 0x401FC: Basic PCIe registers
181        .E1_ADDR(20'h40200), .E1_MASK(20'hFFE00),     //0x40200 - 0x403FC: TX DMA Config/Readback registers
182        .E2_ADDR(20'h40400), .E2_MASK(20'hFFE00),     //0x40400 - 0x405FC: RX DMA Config/Readback registers
183        .E3_ADDR(20'h60000), .E3_MASK(20'hE0000)      //0x60000 - 0x7FFFC: Client address space
184    ) iop2_msg_arbiter (
185        .clk(bus_clk), .reset(bus_rst),
186        //Master
187        .regi_tdata(msgi_tdata), .regi_tvalid(msgi_tvalid), .regi_tready(msgi_tready),
188        .rego_tdata(msgo_tdata), .rego_tvalid(msgo_tvalid), .rego_tready(msgo_tready),
189        //Endpoint 0
190        .e0_regi_tdata(basic_regi_tdata), .e0_regi_tvalid(basic_regi_tvalid), .e0_regi_tready(basic_regi_tready),
191        .e0_rego_tdata(basic_rego_tdata), .e0_rego_tvalid(basic_rego_tvalid), .e0_rego_tready(basic_rego_tready),
192        //Endpoint 1
193        .e1_regi_tdata(dmatx_regi_tdata), .e1_regi_tvalid(dmatx_regi_tvalid), .e1_regi_tready(dmatx_regi_tready),
194        .e1_rego_tdata(dmatx_rego_tdata), .e1_rego_tvalid(dmatx_rego_tvalid), .e1_rego_tready(dmatx_rego_tready),
195        //Endpoint 2
196        .e2_regi_tdata(dmarx_regi_tdata), .e2_regi_tvalid(dmarx_regi_tvalid), .e2_regi_tready(dmarx_regi_tready),
197        .e2_rego_tdata(dmarx_rego_tdata), .e2_rego_tvalid(dmarx_rego_tvalid), .e2_rego_tready(dmarx_rego_tready),
198        //Endpoint 3
199        .e3_regi_tdata(regi_tdata), .e3_regi_tvalid(regi_tvalid), .e3_regi_tready(regi_tready),
200        .e3_rego_tdata(rego_tdata), .e3_rego_tvalid(rego_tvalid), .e3_rego_tready(rego_tready)
201    );
202    assign regi_tlast = regi_tvalid;
203
204    wire [15:0] fpga_status;
205    assign fpga_status[7:0]    = {|(dmatx_error), 1'b0, dmatx_enabled};
206    assign fpga_status[15:8]   = {|(dmarx_error), 1'b0, dmarx_enabled};
207
208    pcie_basic_regs #(
209        .SIGNATURE(32'h58333030 /*ASCII:"X300"*/), .CLK_FREQ(BUS_CLK_RATE)
210    ) basic_regs (
211        .clk(bus_clk), .reset(bus_rst),
212        .regi_tdata(basic_regi_tdata), .regi_tvalid(basic_regi_tvalid), .regi_tready(basic_regi_tready),
213        .rego_tdata(basic_rego_tdata), .rego_tvalid(basic_rego_tvalid), .rego_tready(basic_rego_tready),
214        .misc_status({fpga_status, misc_status})
215    );
216
217    pcie_dma_ctrl #(
218        .NUM_STREAMS(NUM_TX_STREAMS), .FRAME_SIZE_W(DMA_FRAME_SIZE_WIDTH),
219        .REG_BASE_ADDR(20'h40200), .ENABLE_ROUTER(0)
220    ) tx_dma_ctrl_regs (
221        .clk(bus_clk), .reset(bus_rst),
222        .regi_tdata(dmatx_regi_tdata), .regi_tvalid(dmatx_regi_tvalid), .regi_tready(dmatx_regi_tready),
223        .rego_tdata(dmatx_rego_tdata), .rego_tvalid(dmatx_rego_tvalid), .rego_tready(dmatx_rego_tready),
224        .set_enabled(dmatx_enabled), .set_clear(dmatx_clear), .set_frame_size(dmatx_frame_size),
225        .sample_stb(dmatx_samp_stb), .packet_stb(dmatx_pkt_stb),
226        .stream_busy(dmatx_busy), .stream_err(dmatx_error), .rtr_sid(8'h00), .rtr_dst()
227    );
228
229    pcie_dma_ctrl #(
230        .NUM_STREAMS(NUM_RX_STREAMS), .FRAME_SIZE_W(DMA_FRAME_SIZE_WIDTH),
231        .REG_BASE_ADDR(20'h40400), .ENABLE_ROUTER(0)
232    ) rx_dma_ctrl_regs (
233        .clk(bus_clk), .reset(bus_rst),
234        .regi_tdata(dmarx_regi_tdata), .regi_tvalid(dmarx_regi_tvalid), .regi_tready(dmarx_regi_tready),
235        .rego_tdata(dmarx_rego_tdata), .rego_tvalid(dmarx_rego_tvalid), .rego_tready(dmarx_rego_tready),
236        .set_enabled(dmarx_enabled), .set_clear(dmarx_clear), .set_frame_size(dmarx_frame_size),
237        .sample_stb(dmarx_samp_stb), .packet_stb(dmarx_pkt_stb),
238        .stream_busy(dmarx_busy), .stream_err(dmarx_error), .rtr_sid(8'h00), .rtr_dst()
239    );
240    //
241    //*******************************************************************************
242
243    //*******************************************************************************
244    // TX DMA Datapath
245    //
246    wire [(NUM_TX_STREAMS*DMA_STREAM_WIDTH)-1:0]    dmatx_tdata_bclk,  dmatx_tdata_in, dmatx_tdata_trun,  dmatx_tdata_gt, dmatx_tdata_swap;
247    wire [NUM_TX_STREAMS-1:0]                       dmatx_tvalid_bclk, dmatx_tvalid_in, dmatx_tvalid_trun, dmatx_tvalid_gt;
248    wire [NUM_TX_STREAMS-1:0]                       dmatx_tready_bclk, dmatx_tready_in, dmatx_tready_trun, dmatx_tready_gt;
249    wire [NUM_TX_STREAMS-1:0]                       dmatx_tlast_trun,  dmatx_tlast_gt;
250    // Output of the axi_mux8
251    wire [DMA_STREAM_WIDTH-1:0]                     dmatx_tdata_mux;
252    wire [DMA_RX_DEST_WIDTH-1:0]                    dmatx_tuser_mux;
253    wire                                            dmatx_tvalid_mux, dmatx_tlast_mux, dmatx_tready_mux;
254
255    genvar i;
256    generate
257        for (i=0; i<NUM_TX_STREAMS; i=i+1) begin: tx_dma_stuff_generator
258            axi_fifo_2clk #(.WIDTH(DMA_STREAM_WIDTH), .SIZE(DMA_CLK_XING_FIFO_SIZE)) tx_dma_clock_crossing_fifo (
259                .reset(bus_rst),
260                .i_aclk(ioport2_clk), .i_tdata(`GET_DMA_BUS(dmatx_tdata_iop2,i)), .i_tvalid(dmatx_tvalid_iop2[i]), .i_tready(dmatx_tready_iop2[i]),
261                .o_aclk(bus_clk), .o_tdata(`GET_DMA_BUS(dmatx_tdata_bclk,i)), .o_tvalid(dmatx_tvalid_bclk[i]), .o_tready(dmatx_tready_bclk[i])
262            );
263
264            pcie_lossy_samp_gate tx_samp_gate (
265                .i_tdata(`GET_DMA_BUS(dmatx_tdata_bclk,i)), .i_tvalid(dmatx_tvalid_bclk[i]), .i_tready(dmatx_tready_bclk[i]),
266                .o_tdata(`GET_DMA_BUS(dmatx_tdata_in,i)), .o_tvalid(dmatx_tvalid_in[i]), .o_tready(dmatx_tready_in[i]),
267                .drop(~dmatx_enabled[i]), .dropping(dmatx_busy[i])
268            );
269
270            chdr_dechunker tx_dma_dechunker (
271                .clk(bus_clk), .reset(bus_rst), .clear(dmatx_clear[i]), .frame_size(`GET_FSIZE_BUS(dmatx_frame_size, i)),
272                .i_tdata(`GET_DMA_BUS(dmatx_tdata_in,i)), .i_tvalid(dmatx_tvalid_in[i]), .i_tready(dmatx_tready_in[i]),
273                .o_tdata(`GET_DMA_BUS(dmatx_tdata_trun,i)), .o_tlast(dmatx_tlast_trun[i]), .o_tvalid(dmatx_tvalid_trun[i]), .o_tready(dmatx_tready_trun[i]),
274                .error(dmatx_error[i])
275            );
276            assign dmatx_samp_stb[i] = dmatx_tvalid_trun[i] & dmatx_tready_trun[i];
277            assign dmatx_pkt_stb[i] = dmatx_samp_stb[i] & dmatx_tlast_trun[i];
278
279            axi_packet_gate #(.WIDTH(DMA_STREAM_WIDTH), .SIZE(DMA_PKT_GATE_FIFO_SIZE)) vita_chdr_gate (
280                .clk(bus_clk), .reset(bus_rst), .clear(dmatx_clear[i]),
281                .i_tdata(`GET_DMA_BUS(dmatx_tdata_trun,i)), .i_tlast(dmatx_tlast_trun[i]), .i_tvalid(dmatx_tvalid_trun[i]), .i_tready(dmatx_tready_trun[i]),
282                .i_terror(dmatx_error[i]),
283                .o_tdata(`GET_DMA_BUS(dmatx_tdata_gt,i)), .o_tlast(dmatx_tlast_gt[i]), .o_tvalid(dmatx_tvalid_gt[i]), .o_tready(dmatx_tready_gt[i])
284            );
285        end
286    endgenerate
287
288    // [DrB] The following transport adapter requires a tuser input with the DMA
289    // channel. Neither axi_mux8 nor axi_fifo_flop2 support tuser at the time of
290    // this modification, and to reduce the risk we will simply widen tdata and
291    // include the tuser value in there.
292    axi_mux8 #(.PRIO(0), .WIDTH(DMA_STREAM_WIDTH+DMA_RX_DEST_WIDTH)) output_dma_mux (
293        .clk(bus_clk), .reset(bus_rst), .clear(|(dmatx_clear)),
294        .i0_tdata({3'd0, `GET_DMA_BUS(dmatx_tdata_gt,0)}), .i0_tlast(dmatx_tlast_gt[0]), .i0_tvalid(dmatx_tvalid_gt[0]), .i0_tready(dmatx_tready_gt[0]),
295        .i1_tdata({3'd1, `GET_DMA_BUS(dmatx_tdata_gt,1)}), .i1_tlast(dmatx_tlast_gt[1]), .i1_tvalid(dmatx_tvalid_gt[1]), .i1_tready(dmatx_tready_gt[1]),
296        .i2_tdata({3'd2, `GET_DMA_BUS(dmatx_tdata_gt,2)}), .i2_tlast(dmatx_tlast_gt[2]), .i2_tvalid(dmatx_tvalid_gt[2]), .i2_tready(dmatx_tready_gt[2]),
297        .i3_tdata({3'd3, `GET_DMA_BUS(dmatx_tdata_gt,3)}), .i3_tlast(dmatx_tlast_gt[3]), .i3_tvalid(dmatx_tvalid_gt[3]), .i3_tready(dmatx_tready_gt[3]),
298        .i4_tdata({3'd4, `GET_DMA_BUS(dmatx_tdata_gt,4)}), .i4_tlast(dmatx_tlast_gt[4]), .i4_tvalid(dmatx_tvalid_gt[4]), .i4_tready(dmatx_tready_gt[4]),
299        .i5_tdata({3'd5, `GET_DMA_BUS(dmatx_tdata_gt,5)}), .i5_tlast(dmatx_tlast_gt[5]), .i5_tvalid(dmatx_tvalid_gt[5]), .i5_tready(dmatx_tready_gt[5]),
300        .i6_tdata({3'd6, 0}), .i6_tlast(1'b0), .i6_tvalid(1'b0), .i6_tready(),
301        .i7_tdata({3'd7, 0}), .i7_tlast(1'b0), .i7_tvalid(1'b0), .i7_tready(),
302        .o_tdata({dmatx_tuser_mux, dmatx_tdata_mux}),
303        .o_tlast(dmatx_tlast_mux), .o_tvalid(dmatx_tvalid_mux), .o_tready(dmatx_tready_mux)
304    );
305
306    axi_fifo_flop2 #(.WIDTH(DMA_STREAM_WIDTH+1+DMA_RX_DEST_WIDTH)) tx_pipeline_reg (
307        .clk(bus_clk), .reset(bus_rst), .clear(|(dmatx_clear)),
308        .i_tdata({dmatx_tuser_mux, dmatx_tlast_mux, dmatx_tdata_mux}),
309        .i_tvalid(dmatx_tvalid_mux), .i_tready(dmatx_tready_mux),
310        .o_tdata({dmatx_tuser, dmatx_tlast, dmatx_tdata}),
311        .o_tvalid(dmatx_tvalid), .o_tready(dmatx_tready),
312        .space(), .occupied());
313    //
314    //*******************************************************************************
315
316    //*******************************************************************************
317    // RX DMA Datapath
318    //
319    wire [(NUM_RX_STREAMS*DMA_STREAM_WIDTH)-1:0]    dmarx_tdata_bclk,  dmarx_tdata_pad, dmarx_tdata_swap, dmarx_tdata_out;
320    wire [NUM_RX_STREAMS-1:0]                       dmarx_tvalid_bclk, dmarx_tvalid_pad, dmarx_tvalid_out;
321    wire [NUM_RX_STREAMS-1:0]                       dmarx_tready_bclk, dmarx_tready_pad, dmarx_tready_out;
322    wire [NUM_RX_STREAMS-1:0]                       dmarx_tlast_bclk,  dmarx_tlast_pad, dmarx_tlast_out;
323
324    wire [DMA_STREAM_WIDTH-1:0]                     dmarx_tdata_mux;
325    wire [DMA_RX_DEST_WIDTH-1:0]                    dmarx_tuser_mux;
326    wire                                            dmarx_tvalid_mux, dmarx_tlast_mux, dmarx_tready_mux;
327
328    axi_fifo_flop2 #(.WIDTH(DMA_STREAM_WIDTH+1+DMA_RX_DEST_WIDTH)) rx_pipeline_reg (
329        .clk(bus_clk), .reset(bus_rst), .clear(|(dmarx_clear)),
330        .i_tdata({dmarx_tuser, dmarx_tlast, dmarx_tdata}),
331        .i_tvalid(dmarx_tvalid), .i_tready(dmarx_tready),
332        .o_tdata({dmarx_tuser_mux, dmarx_tlast_mux, dmarx_tdata_mux}),
333        .o_tvalid(dmarx_tvalid_mux), .o_tready(dmarx_tready_mux),
334        .space(), .occupied());
335
336    axi_demux8 #(.ACTIVE_CHAN(8'b00111111), .WIDTH(DMA_STREAM_WIDTH)) input_dma_demux (
337        .clk(bus_clk), .reset(bus_rst), .clear(|(dmarx_clear)),
338        .header(), .dest(dmarx_tuser_mux),
339        .i_tdata(dmarx_tdata_mux), .i_tlast(dmarx_tlast_mux), .i_tvalid(dmarx_tvalid_mux), .i_tready(dmarx_tready_mux),
340        .o0_tdata(`GET_DMA_BUS(dmarx_tdata_bclk,0)), .o0_tlast(dmarx_tlast_bclk[0]), .o0_tvalid(dmarx_tvalid_bclk[0]), .o0_tready(dmarx_tready_bclk[0]),
341        .o1_tdata(`GET_DMA_BUS(dmarx_tdata_bclk,1)), .o1_tlast(dmarx_tlast_bclk[1]), .o1_tvalid(dmarx_tvalid_bclk[1]), .o1_tready(dmarx_tready_bclk[1]),
342        .o2_tdata(`GET_DMA_BUS(dmarx_tdata_bclk,2)), .o2_tlast(dmarx_tlast_bclk[2]), .o2_tvalid(dmarx_tvalid_bclk[2]), .o2_tready(dmarx_tready_bclk[2]),
343        .o3_tdata(`GET_DMA_BUS(dmarx_tdata_bclk,3)), .o3_tlast(dmarx_tlast_bclk[3]), .o3_tvalid(dmarx_tvalid_bclk[3]), .o3_tready(dmarx_tready_bclk[3]),
344        .o4_tdata(`GET_DMA_BUS(dmarx_tdata_bclk,4)), .o4_tlast(dmarx_tlast_bclk[4]), .o4_tvalid(dmarx_tvalid_bclk[4]), .o4_tready(dmarx_tready_bclk[4]),
345        .o5_tdata(`GET_DMA_BUS(dmarx_tdata_bclk,5)), .o5_tlast(dmarx_tlast_bclk[5]), .o5_tvalid(dmarx_tvalid_bclk[5]), .o5_tready(dmarx_tready_bclk[5]),
346        .o6_tdata(), .o6_tlast(), .o6_tvalid(), .o6_tready(1'b0), //Unused port
347        .o7_tdata(), .o7_tlast(), .o7_tvalid(), .o7_tready(1'b0)  //Unused port
348    );
349
350    genvar j;
351    generate
352        for (j=0; j<NUM_RX_STREAMS; j=j+1) begin: rx_dma_stuff_generator
353            assign dmarx_samp_stb[j] = dmarx_tvalid_bclk[j] & dmarx_tready_bclk[j];
354            assign dmarx_pkt_stb[j] = dmarx_samp_stb[j] & dmarx_tlast_bclk[j];
355
356            chdr_chunker rx_dma_chunker (
357                .clk(bus_clk), .reset(bus_rst), .clear(dmarx_clear[j]), .frame_size(`GET_FSIZE_BUS(dmarx_frame_size, j)),
358                .i_tdata(`GET_DMA_BUS(dmarx_tdata_bclk,j)), .i_tlast(dmarx_tlast_bclk[j]), .i_tvalid(dmarx_tvalid_bclk[j]), .i_tready(dmarx_tready_bclk[j]),
359                .o_tdata(`GET_DMA_BUS(dmarx_tdata_pad,j)), .o_tlast(dmarx_tlast_pad[j]), .o_tvalid(dmarx_tvalid_pad[j]), .o_tready(dmarx_tready_pad[j]),
360                .error(dmarx_error[j])
361            );
362
363            pcie_lossy_samp_gate rx_samp_gate (
364                .i_tdata(`GET_DMA_BUS(dmarx_tdata_pad,j)), .i_tvalid(dmarx_tvalid_pad[j]), .i_tready(dmarx_tready_pad[j]),
365                .o_tdata(`GET_DMA_BUS(dmarx_tdata_out,j)), .o_tvalid(dmarx_tvalid_out[j]), .o_tready(dmarx_tready_out[j]),
366                .drop(~dmarx_enabled[j]), .dropping(dmarx_busy[j])
367            );
368
369            axi_fifo_2clk #(.WIDTH(DMA_STREAM_WIDTH), .SIZE(DMA_CLK_XING_FIFO_SIZE)) rx_dma_clock_crossing_fifo (
370                .reset(bus_rst),
371                .i_aclk(bus_clk), .i_tdata(`GET_DMA_BUS(dmarx_tdata_out,j)), .i_tvalid(dmarx_tvalid_out[j]), .i_tready(dmarx_tready_out[j]),
372                .o_aclk(ioport2_clk), .o_tdata(`GET_DMA_BUS(dmarx_tdata_iop2,j)), .o_tvalid(dmarx_tvalid_iop2[j]), .o_tready(dmarx_tready_iop2[j])
373            );
374        end
375    endgenerate
376    //
377    //*******************************************************************************
378endmodule // x300_pcie_int
379
380`undef GET_DMA_BUS
381`undef GET_FSIZE_BUS
382`undef GET_SWAP_BUS
383