OpenCores
URL https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [source/] [pcie_blk_ll_tx_arb.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dsmv
 
2
//-----------------------------------------------------------------------------
3
//
4
// (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
5
//
6
// This file contains confidential and proprietary information
7
// of Xilinx, Inc. and is protected under U.S. and
8
// international copyright and other intellectual property
9
// laws.
10
//
11
// DISCLAIMER
12
// This disclaimer is not a license and does not grant any
13
// rights to the materials distributed herewith. Except as
14
// otherwise provided in a valid license issued to you by
15
// Xilinx, and to the maximum extent permitted by applicable
16
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
17
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
18
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
19
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
20
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
21
// (2) Xilinx shall not be liable (whether in contract or tort,
22
// including negligence, or under any other theory of
23
// liability) for any loss or damage of any kind or nature
24
// related to, arising under or in connection with these
25
// materials, including for any direct, or any indirect,
26
// special, incidental, or consequential loss or damage
27
// (including loss of data, profits, goodwill, or any type of
28
// loss or damage suffered as a result of any action brought
29
// by a third party) even if such damage or loss was
30
// reasonably foreseeable or Xilinx had been advised of the
31
// possibility of the same.
32
//
33
// CRITICAL APPLICATIONS
34
// Xilinx products are not designed or intended to be fail-
35
// safe, or for use in any application requiring fail-safe
36
// performance, such as life-support or safety devices or
37
// systems, Class III medical devices, nuclear facilities,
38
// applications related to the deployment of airbags, or any
39
// other applications that could lead to death, personal
40
// injury, or severe property or environmental damage
41
// (individually and collectively, "Critical
42
// Applications"). Customer assumes the sole risk and
43
// liability of any use of Xilinx products in Critical
44
// Applications, subject only to applicable laws and
45
// regulations governing limitations on product liability.
46
//
47
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
48
// PART OF THIS FILE AT ALL TIMES.
49
//
50
//-----------------------------------------------------------------------------
51
// Project    : V5-Block Plus for PCI Express
52
// File       : pcie_blk_ll_tx_arb.v
53
//--------------------------------------------------------------------------------
54
//--------------------------------------------------------------------------------
55
/*****************************************************************************
56
 *  Description : PCIe Block Plus Tx Arbiter - multiplexes input to the
57
 *    PCIE Block between the user input and bridge-generated traffic (such
58
 *    as interrupts and config TLPs)
59
 ****************************************************************************/
60
 
61
`timescale 1ns/1ns
62
`ifndef TCQ
63
 `define TCQ 1
64
`endif
65
 
66
module pcie_blk_ll_tx_arb
67
  (
68
   // Clock and reset
69
 
70
   input             clk,
71
   input             rst_n,
72
 
73
   // Transaction Link Up
74
 
75
//   input             trn_lnk_up_n,  // Might need this for discontinue
76
 
77
   // Tx Bridge Ports
78
   output reg [63:0] tx_td,
79
   output reg        tx_sof_n,
80
   output reg        tx_eof_n,
81
   output [7:0]      tx_rem_n,
82
   output reg        tx_src_dsc_n = 1'b1,
83
   output reg        tx_src_rdy_n = 1'b1,
84
   input             tx_dst_rdy_n,
85
 
86
   // User (TRN) Tx Ports
87
 
88
   input [63:0]      trn_td,
89
   input [7:0]       trn_trem_n,
90
   input             trn_tsof_n,
91
   input             trn_teof_n,
92
   input             trn_tsrc_rdy_n,
93
   input             trn_tsrc_dsc_n,
94
 
95
   output reg        trn_tdst_rdy_n = 1'b1,
96
   output            trn_tdst_dsc_n,
97
 
98
   // Config Tx Ports
99
 
100
   input [63:0]      cfg_tx_td,
101
   input             cfg_tx_rem_n,
102
   input             cfg_tx_sof_n,
103
   input             cfg_tx_eof_n,
104
   input             cfg_tx_src_rdy_n,
105
   output reg        cfg_tx_dst_rdy_n = 1'b1
106
   );
107
 
108
  reg                cfg_in_pkt = 1'b0;
109
  reg                usr_in_pkt = 1'b0;
110
  wire               cfg_start;
111
  wire               cfg_done;
112
  wire               usr_start;
113
  wire               usr_done;
114
  wire               usr_in_pkt_inc;  // Inclusive of SOF cycle
115
 
116
  reg [63:0]         buf_td;
117
  reg                buf_sof_n;
118
  reg                buf_eof_n;
119
  reg                buf_dsc_n = 1'b1;
120
  reg                buf_rem_n;
121
  reg                buf_vld = 1'b0;
122
  wire               buf_divert;
123
  wire               buf_rd;
124
  wire               buf_filling;
125
 
126
  reg                tx_rem_n_bit;
127
 
128
  // Assign static output to undriven signals
129
  assign trn_tdst_dsc_n = 1'b1;  // FIXME do we need to do something with this?
130
 
131
  // Generate enables (dst_rdy)
132
  // NOTE this will insert a cycle switching cfg->usr; it is unavoidable
133
  // if we want to allow back-to-back TLPs from the CFG input
134
  always @(posedge clk) begin
135
    if (!rst_n) begin
136
      trn_tdst_rdy_n      <= #`TCQ 1'b1;
137
      cfg_tx_dst_rdy_n    <= #`TCQ 1'b1;
138
    end else begin
139
      if (cfg_in_pkt || ((!usr_in_pkt_inc || usr_done) &&
140
                         !cfg_tx_src_rdy_n)) begin
141
        cfg_tx_dst_rdy_n  <= #`TCQ ((buf_vld && !buf_rd) || buf_filling);
142
        trn_tdst_rdy_n    <= #`TCQ 1'b1;
143
      end else begin
144
        cfg_tx_dst_rdy_n  <= #`TCQ 1'b1;
145
        trn_tdst_rdy_n    <= #`TCQ ((buf_vld && !buf_rd) || buf_filling);
146
      end
147
    end
148
  end
149
 
150
  assign usr_start = !trn_tdst_rdy_n && !trn_tsrc_rdy_n && !trn_tsof_n;
151
  assign usr_done  = !trn_tdst_rdy_n && !trn_tsrc_rdy_n &&
152
                     (!trn_teof_n || !trn_tsrc_dsc_n);
153
  assign usr_in_pkt_inc = usr_in_pkt ||
154
          (!trn_tdst_rdy_n && !trn_tsrc_rdy_n && !trn_tsof_n);
155
 
156
  assign cfg_start = !cfg_tx_dst_rdy_n && !cfg_tx_src_rdy_n && !cfg_tx_sof_n;
157
  assign cfg_done  = !cfg_tx_dst_rdy_n && !cfg_tx_src_rdy_n && !cfg_tx_eof_n;
158
 
159
  // Create usr_in_pkt and cfg_in_pkt
160
  always @(posedge clk) begin
161
    if (!rst_n) begin
162
      usr_in_pkt     <= #`TCQ 1'b0;
163
      cfg_in_pkt     <= #`TCQ 1'b0;
164
    end else begin
165
      if (usr_start) begin
166
        usr_in_pkt   <= #`TCQ 1'b1;
167
      end else if (usr_done) begin
168
        usr_in_pkt   <= #`TCQ 1'b0;
169
      end
170
      if (cfg_start) begin
171
        cfg_in_pkt   <= #`TCQ 1'b1;
172
      end else if (cfg_done) begin
173
        cfg_in_pkt   <= #`TCQ 1'b0;
174
      end
175
    end
176
  end
177
 
178
  // Input shunt buffer - absorb one cycle of data to decouple
179
  // trn_tdst_rdy_n from other signals (and therefore make it a
180
  // registered output)
181
  always @(posedge clk) begin
182
    if (!rst_n) begin
183
      buf_vld         <= #`TCQ 1'b0;
184
    end else begin
185
      if (!trn_tdst_rdy_n && !trn_tsrc_rdy_n && buf_divert) begin
186
        buf_td        <= #`TCQ trn_td;
187
        buf_sof_n     <= #`TCQ trn_tsof_n;
188
        buf_eof_n     <= #`TCQ trn_teof_n && trn_tsrc_dsc_n;
189
        buf_dsc_n     <= #`TCQ trn_tsrc_dsc_n;
190
        buf_rem_n     <= #`TCQ trn_trem_n[0];
191
 
192
        // Prevent user-data outside of a packet (data after EOF and before
193
        // SOF) from being accepted by the core by masking with usr_in_pkt_inc
194
        buf_vld       <= #`TCQ usr_in_pkt_inc;
195
      end else if (!cfg_tx_dst_rdy_n && !cfg_tx_src_rdy_n && buf_divert) begin
196
        buf_td        <= #`TCQ cfg_tx_td;
197
        buf_sof_n     <= #`TCQ cfg_tx_sof_n;
198
        buf_eof_n     <= #`TCQ cfg_tx_eof_n;
199
        buf_dsc_n     <= #`TCQ 1'b1;
200
        buf_rem_n     <= #`TCQ cfg_tx_rem_n;
201
        buf_vld       <= #`TCQ 1'b1;
202
      end else if (buf_rd) begin
203
        buf_vld       <= #`TCQ 1'b0;
204
      end
205
    end
206
  end
207
 
208
  // Control when the shunt buffer is written and read
209
  //   Writes go to the shunt buffer when the first pipeline stage is full
210
  //   and not emptying
211
  assign buf_divert = !tx_src_rdy_n && tx_dst_rdy_n;
212
  //   The shunt buffer gets read when the pipeline is first shifted after
213
  //   the shunt buffer is filled
214
  assign buf_rd     = buf_vld && !tx_src_rdy_n && !tx_dst_rdy_n;
215
  //   Asserted if the shunt buffer is filling
216
  assign buf_filling = buf_divert &&
217
                       ((!cfg_tx_src_rdy_n && !cfg_tx_dst_rdy_n) ||
218
                        (!trn_tsrc_rdy_n && !trn_tdst_rdy_n));
219
  // Output buffer
220
  always @(posedge clk) begin
221
    if (!rst_n) begin
222
      tx_src_rdy_n      <= #`TCQ 1'b1;
223
    end else begin
224
      // Multiplex the three inputs into the output data
225
      casex ({buf_rd,
226
              (!cfg_tx_src_rdy_n && !cfg_tx_dst_rdy_n && !buf_divert),
227
              (!trn_tsrc_rdy_n && !trn_tdst_rdy_n && !buf_divert)})
228
        3'b1xx: begin
229
          // Buf_rd always has priority. If one of the other sources has
230
          // a successful transaction but we're reading from the buffer,
231
          // that incoming transaction goes into the buffer, not the output
232
          tx_td         <= #`TCQ buf_td;
233
          tx_sof_n      <= #`TCQ buf_sof_n;
234
          tx_eof_n      <= #`TCQ buf_eof_n;
235
          tx_src_dsc_n  <= #`TCQ buf_dsc_n;
236
          tx_rem_n_bit  <= #`TCQ buf_rem_n;
237
        end
238
        3'b010: begin
239
          // Select from config input
240
          tx_td         <= #`TCQ cfg_tx_td;
241
          tx_sof_n      <= #`TCQ cfg_tx_sof_n;
242
          tx_eof_n      <= #`TCQ cfg_tx_eof_n;
243
          tx_src_dsc_n  <= #`TCQ 1'b1;
244
          tx_rem_n_bit  <= #`TCQ cfg_tx_rem_n;
245
        end
246
        3'b001: begin
247
          // Select from user input
248
          tx_td         <= #`TCQ trn_td;
249
          tx_sof_n      <= #`TCQ trn_tsof_n;
250
          tx_eof_n      <= #`TCQ trn_teof_n && trn_tsrc_dsc_n;
251
          tx_src_dsc_n  <= #`TCQ trn_tsrc_dsc_n;
252
          tx_rem_n_bit  <= #`TCQ trn_trem_n;
253
        end
254
        3'b000: ; // This case is OK - don't have to move data every cycle
255
        default: begin
256
          // Anything other than the above cases is BAD
257
          // synthesis translate_off
258
          $display("ERROR: pcie_blk_ll_tx_arb hit an illegal mux input combination");
259
          $finish;
260
          // synthesis translate_on
261
        end
262
      endcase
263
 
264
      // Generate the output-valid signal
265
      // Prevent user-data outside of a packet (data after EOF and before
266
      // SOF) from being accepted by the core by masking with usr_in_pkt_inc
267
      if (buf_rd || (!cfg_tx_src_rdy_n && !cfg_tx_dst_rdy_n) ||
268
          (!trn_tsrc_rdy_n && !trn_tdst_rdy_n && usr_in_pkt_inc)) begin
269
        tx_src_rdy_n    <= #`TCQ 1'b0;
270
      end else if (!tx_dst_rdy_n) begin
271
        tx_src_rdy_n    <= #`TCQ 1'b1;
272
      end
273
    end
274
  end
275
 
276
  // REM is an 8-bit signal into the existing bridge code (although
277
  // only 1 bit is actually used) so we synthesize the rest of it here
278
  assign tx_rem_n = {4'b0000, {4{tx_rem_n_bit}}};
279
 
280
endmodule // pcie_blk_ll_tx_arb
281
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.